Java 在对线程调用start和运行实际启动之间,我们可以插入其他命令吗?
我正在学习OCP认证,我必须根据下面的片段回答一个问题 让我困惑的是,在Java 在对线程调用start和运行实际启动之间,我们可以插入其他命令吗?,java,multithreading,Java,Multithreading,我正在学习OCP认证,我必须根据下面的片段回答一个问题 让我困惑的是,在t完成执行之前,我们能保证当前线程在t上连接吗 对我来说,r1r2m1m2似乎是一种可能的输出 我怎么想的不对 class Infinity implements Runnable { public static void main(String [] args) throws Exception { Thread t = new Thread(new Infinity()); t.start();
t
完成执行之前,我们能保证当前线程在t
上连接吗
对我来说,r1
r2
m1
m2
似乎是一种可能的输出
我怎么想的不对
class Infinity implements Runnable {
public static void main(String [] args) throws Exception {
Thread t = new Thread(new Infinity());
t.start();
System.out.println("m1 ");
t.join();
System.out.println("m2 ");
}
public void run() {
System.out.println("r1 ");
System.out.println("r2 ");
}
}
多线程从来都不容易。这是因为您无法保证代码的特定部分何时启动 在本例中,您有两个线程:主线程“m”和第二个线程“r” 首先:主线程(m)将通过执行程序启动。 然后它立即生成另一个线程(r)并启动它(
t.start()
)
现在有两个独立运行的线程:m和r。
除非您没有指定它,否则它们可以按任何可能的顺序执行,但是-您可以在某个时候使用t.join()
指定它。t.start()
和t.join()
之间的m线程中的所有内容都可以在r线程期间的任何时间执行。这可能是以下顺序:
-m1 r1 r2
-r1 m1 r2
-r1 r2 m1
由于t.join()
,只有m2被限制为等待r完成
因此,
r1r2m1mm2
可能是一个输出,但它也可能是m1r2m2
或r1m1r2m2
不,它打印:m1r1m2
在某些情况下是必须的,因为一旦我们启动一个线程,我们就继续执行其余的代码,在这种情况下,它就是打印m1
,但有时在线程之间切换可能需要一段时间,在这种情况下,我们可能会得到r1 m1 r2 m2
或r1 r2 m1 m2
,如下两个示例:
此示例很可能打印r1r2m1m2
(但不是100%),因为当我们看到sleep(10)线程时,我们有时间继续其他线程:
这个例子很可能打印出r1m1r2m2
(但不是100%),这是因为当我们看到sleep(100)时,我们有时间回到主线程:
最后,我认为对您来说很明显,
m2
最后打印。此代码中只有三个保证:
- m1发生在m2之前(因为它们在同一线程中)
- r1发生在r2之前(因为它们在同一线程中)
- r2发生在m2之前(线程
的执行保证在t
t.join()可以返回之前完成)
m1 r1 r2 m2
r1 m1 r2 m2
r1 r2 m1 m2
如果m1的打印在调用t.start()
之前,而不是之后,那么将引入第四个保证
- m1发生在r1之前(因为线程中的操作总是在该线程的开始之后)
m1 r1 r2 m2
添加:
t.join()
保证,m2
总是最后一个。酷,这正是我所想的:)对你来说真的是“预期的”或者更确切地说是“可能的”?你是对的,Cheers我理解睡眠的事情,但是JVM在线程刚启动时就将其置于睡眠状态的可能性有多大(或者,如果您愿意,就在第一个run命令之前),没有显式的sleep调用?@py_script Jvm没有将其置于睡眠状态,Jvm只是继续运行主线程,而没有切换到另一个线程。我问的原因是,在我的示例中,为什么它可能不首先运行print r1(没有显式的睡眠调用)
m1 r1 r2 m2
r1 m1 r2 m2
r1 r2 m1 m2
m1 r1 r2 m2