例如:
public class Example1 {
public static void main(String[] args) {
Loop loop = new Loop();
loop.start(); //printing "Before start"
System.out.println("After start");
}
}
可能是loop
的run方法在执行打印的最后一行之前完成的情况" After Start"?
答案 0 :(得分:41)
一旦你开始多线程,你最好放弃关于线程运行顺序的所有假设。
如果它很重要,你可以使用同步操作,但没有它们,所有的赌注都会被关闭。
答案 1 :(得分:11)
是的,您无法控制JVM如何执行/调度线程。
如果要引入某种排序(按顺序执行两个线程),最简单的方法是使用Java提供的Lock
对象之一。
答案 2 :(得分:11)
你基本上是在询问Java中的线程安全性(至少这是我从这个问题中理解的)。正如之前的答案之一已经说明的那样,在运行多个线程时放弃关于执行顺序的任何假设是个好主意。
然而(!),可以使用设计原则和批判性思维来模拟您的应用程序,使得多线程不会发生不希望的副作用。
对于初学者,您可以在Designing Object Initilization上阅读这篇文章
本文的要点是,您应该将您的课程视为finite state machines
。如果你不知道它们是什么:finite state machines
在一组状态中运行(因此名称)。
这个想法是当你处于状态(A)
时,你可以定义这个特定状态可以执行的行为:(A) -> (B), (A) -> (C)
我可以从状态(A)
转到状态(B)
和(C)
但不能转到状态(D)
(如果存在的话)这种思维模式对于了解您的应用 CAN很重要在任何特定情况下都可以。 (Fine State Machines Wikipedia)
一旦你理解了这一点,你就可以继续前进 修复:
有三种方法可以使对象线程安全:
每种方法都有自己的优点/缺点,这些优点/缺点在Java文档中有解释:
希望这可以让您更好地了解创建多线程应用程序时可能遇到的复杂情况。
答案 3 :(得分:6)
如果我在线程上添加一个连接和一些打印语句,那么可以解释一些特性。
public class Example1 {
public static void main(String[] args) {
Loop loop = new Loop();
System.out.println("Before start");
loop.start(); //printing "Before start"
System.out.println("After start");
loop.join();
System.out.println("After join");
}
}
“开始之前”将在loop.run()
执行之前打印始终。
“加入后”将在loop.run()
完成后始终打印。
“开始后”无法保证何时打印相对于loop.run()
;它可以在之前,它可以在之后,它可以在执行期间与loop.run()中的print语句交错。
如果您确实需要保证,那么您需要其他同步实用程序,如锁和信号量。