Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么这个主方法没有被终止?_Java_Multithreading - Fatal编程技术网

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

我不熟悉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 {

    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啊,这就是我错过的细节。谢谢。