Java 为什么这个主方法没有被终止?
我不熟悉java中的多线程,我正在尝试编写一个简单的程序来模拟线程间的通信 问题是我的Java 为什么这个主方法没有被终止?,java,multithreading,Java,Multithreading,我不熟悉java中的多线程,我正在尝试编写一个简单的程序来模拟线程间的通信 问题是我的main方法在交换下面两行之前不会终止 t1.start();// if I call t2.start() first and then t1.start() then it works perfectly t2.start(); 有人能解释一下为什么我需要在t1.start()之前调用t2.start()? 这是我的密码 public class WaitNotifyExample { publ
main
方法在交换下面两行之前不会终止
t1.start();// if I call t2.start() first and then t1.start() then it works perfectly
t2.start();
有人能解释一下为什么我需要在t1.start()之前调用t2.start()?
这是我的密码
public class WaitNotifyExample {
public static void main(String[] args) throws InterruptedException {
System.out.println("main method starts");
A a = new A();
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
a.printNumbers();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
a.afterPrintNumbers();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// This works fine but I don't understand why..
t2.start();
t1.start();
t1.join();
t2.join();
System.out.println("main method ends");
}
}
class A{
public void printNumbers() throws InterruptedException{
synchronized(this){
for(int i = 0;i<10;i++){
System.out.println(i);
}
this.notify();
}
}
public void afterPrintNumbers() throws InterruptedException{
synchronized(this){
this.wait();
System.out.println("all no. printed");
}
}
}
公共类waitnotify示例{
公共静态void main(字符串[]args)引发InterruptedException{
System.out.println(“主方法启动”);
A=新的A();
线程t1=新线程(新的可运行线程(){
公开募捐{
试一试{
a、 打印号码();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
});
线程t2=新线程(新可运行(){
公开募捐{
试一试{
a、 后印本编号();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
});
//这很好,但我不明白为什么。。
t2.start();
t1.start();
t1.join();
t2.连接();
System.out.println(“主要方法结束”);
}
}
甲级{
public void printNumbers()引发InterruptedException{
已同步(此){
对于(int i=0;i
如果我先调用t2.start(),然后调用t1.start(),那么它就可以正常工作
不能保证
P> >考虑,<代码> T1 执行<代码> .NoTIFY();<代码> >,然后>代码> T2< /Cord>执行<代码> .WaIT(;)/<代码> ./P>
在这种情况下,t2
将永远不会收到信号
如果我先调用t2.start(),然后调用t1.start(),那么它就可以正常工作
不能保证
P> >考虑,<代码> T1 执行<代码> .NoTIFY();<代码> >,然后>代码> T2< /Cord>执行<代码> .WaIT(;)/<代码> ./P>
在这种情况下,t2
将永远不会收到信号。线程执行的顺序没有保证,它取决于线程调度程序算法
因此,在您的情况下,JVM选择t1并完成执行this.notify()
,然后t2执行this.wait()
,如前所述。线程执行的顺序没有保证,它取决于线程调度程序算法
因此,在您的情况下,JVM选择t1并完成执行this.notify()
,然后t2执行前面提到的this.wait()
。这里实际上不保证吗,因为如果t2
首先执行this.wait()
,那么t1
将永远不会到达this.notify()
因为t2
持有同步锁?我遗漏了什么吗?要明确这一点:首先启动t1使这种情况更可能发生,但首先启动t2仍然使其成为可能。对于多线程代码来说,非常重要的是要证明您想要的行为不仅仅是可能的,不仅仅是可能的,而且是唯一的不可能的行为。否则,它可能会偶尔出现故障,并且在生产中很难进行诊断和测试fix@marstran仅仅因为t2.start()首先被调用,并不意味着它的run()方法将首先运行。的JVM完全有权启动线程,立即停止线程,并执行其他工作(包括开始t1)。@yshavit解释得很好。@yshavit啊,这就是我错过的细节。谢谢。这里不是真的保证了吗?因为如果t2
首先执行this.wait()
,那么t1
将永远无法到达this.notify()
因为t2
持有同步锁?我遗漏了什么吗?要明确这一点:首先启动t1使这种情况更可能发生,但首先启动t2仍然使其成为可能。对于多线程代码来说,非常重要的是要证明您想要的行为不仅仅是可能的,不仅仅是可能的,而且是唯一的不可能的行为。否则,它可能会偶尔出现故障,并且在生产中很难进行诊断和测试fix@marstran仅仅因为t2.start()首先被调用,并不意味着它的run()方法将首先运行。的JVM完全有权启动线程,立即停止线程,并执行其他工作(包括开始t1)。@yshavit解释得很好。@yshavit啊,这就是我错过的细节。谢谢。