我正在阅读"实践中的Java并发"一书。在第二章中,我阅读了语句
任何单线程程序也是一个有效的多线程程序
我听不懂这个说法。
请分享您对此的想法,以便可以消除我的困惑。预先感谢。
但是,如果程序已经不是正确的在单线环境中,那么在更复杂的多螺纹环境中可能是正确的。
从书中:
由于任何单个螺纹程序也是有效的多线程 程序,如果线程在 单线环境。
如果正确实现了对象,则没有操作序列呼叫序列 公共方法和读物或书面公共场应该能够 违反其任何不变性或邮政条件。没有一组 操作在A的实例上依次或同时执行 线程安全类可能导致实例处于无效状态。
和此:
如果此处宽松使用"正确性"会困扰您,您可能更喜欢 认为线程安全类是不再破坏的线 并发环境比在单个螺纹环境中。
@yshavit在考虑多线程正确性之前,请确保您至少具有单线程正确性。
任何单线程程序也是一个有效的多线程程序
这基本上意味着任何单个螺纹程序都可以在多线程上下文中使用。以以下代码为例:
class A {
public void doSomething() { }
}
如果我们孤立地考虑上述类,则显然是一个线程的程序。但是,同一程序也可以在多线程上下文中使用:
Thread thread1 = new Thread(new Runnable() { public void run() { A a = new A(); a.doSomething(); } }).start();
Thread thread2 = new Thread(new Runnable() { public void run() { A a = new A(); a.doSomething(); } }).start();
谈论您没有询问的书中的特定相关段落,但值得讨论:
没有依次或同时执行的一组操作 线程安全类的实例可能导致实例在一个 无效状态
让我们在我们的班级中添加一些状态:
class A {
int iCantBeNegative = 10;
public void doSomething() { --icantBeNegative; }
}
程序员的期望是iCantBeNegative
永远不要小于零,但是,他们没有采取任何行动来执行这一要求。由于从期望的角度来看,该程序主要在单线程上下文中不正确(如果iCantBeNegatvie
在行中称为11次或更多),则在多线程中,它绝对是不正确的。
"任何单线程程序也是有效的多线程程序"
无需读书并阅读本节,在JVM中运行时,单个螺纹应用程序确实是多线程的方法。当JVM启动时,有许多JVM特定线程将分叉。它们包括GC线程,最终确定器,JMX线程(如果启用)等。这些线程在后台运行以帮助JVM有效运行。
例如,在我的OSX框上,以下线程默认分配:
- Main
- 参考处理程序
- 最终器
- 信号调度器
- 附加听众
- 如果启用JMX,则许多RMI和JMX线程
另外,当运行用户应用程序代码的主线程遇到synchronized
块或访问库中的volatile
字段或JDK中的CC_5字段,因此主线程会通过内存屏障,获取和发布锁等。那可能就是作者引用的内容。
最后,重要的是要意识到"重新进入"一词是在发明线程概念之前就创建的。由于递归方法或中断处理程序,必须正确编写代码以重新进入,这意味着即使从未通过多个"线程",代码可以输入两次。在上下文切换,交换/输入,缓存内存等之前,需要编写适当的返回代码。是的,我在这里显示我的年龄。