Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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,在下面的代码中,我使用wait()-notify()实现了线程间通信,它提供了预期的输出。 预期产量:123456789实际产量:123456789 我的问题是,由于线程调度依赖于jvm,是否有任何保证总是“主线程”将获得第一次执行的机会。如果“子线程”得到第一次机会,notify()信号将丢失,“主线程”将永远等待。如何确认“主线程”始终首先执行。另外,请确认以下代码是否可以改进 package com.test.Thread; public class ThreadExample1 {

在下面的代码中,我使用wait()-notify()实现了线程间通信,它提供了预期的输出。 预期产量:123456789实际产量:123456789

我的问题是,由于线程调度依赖于jvm,是否有任何保证总是“主线程”将获得第一次执行的机会。如果“子线程”得到第一次机会,notify()信号将丢失,“主线程”将永远等待。如何确认“主线程”始终首先执行。另外,请确认以下代码是否可以改进

package com.test.Thread;

public class ThreadExample1 {

    public static void main(String[] args) throws InterruptedException{

        ThreadChild1 lockingObj = new ThreadChild1();
        lockingObj .start();
        synchronized(lockingObj ){
            for(int i=1;i<10;i++){
                System.out.println("Main "+i);
            }
            lockingObj.wait();
            System.out.println("Main got notified");

        }

    }

}

class ThreadChild1 extends Thread{

    public void run(){
        synchronized(this){
            for(int i=1;i<10;i++){
                System.out.println("Child "+i);
            }
            this.notify();
            }
    }
}
package com.test.Thread;
公共类线程示例1{
公共静态void main(字符串[]args)引发InterruptedException{
ThreadChild1 lockingObj=新的ThreadChild1();
lockingbj.start();
已同步(锁定对象){

对于(inti=1;i您的代码是错误的,原因是您提到了自己:您无法确定哪个线程先运行。 还有其他可能出错的事情-
等待
可以在没有
通知的情况下醒来

您可以在中阅读,这也解释了您应该做什么:

在单参数版本中,中断和虚假唤醒是非常重要的 可能,并且此方法应始终在循环中使用:

synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
     ... // Perform action appropriate to condition
 }
synchronized(obj){
而()
obj.wait();
…//执行适合条件的操作
}
在您的代码中,您可以使用表示条件“我已收到通知”的布尔变量来解决此问题:

公共类线程示例1{
公共静态void main(字符串[]args)引发InterruptedException{
ThreadChild1 lockingObj=新的ThreadChild1();
lockingbj.start();
已同步(锁定对象){
对于(int i=1;i<10;i++){
系统输出打印项次(“主”+i);
}
而(!lockingbj.haveNotified){
lockingbj.wait();
}
System.out.println(“主收到通知”);
}
}
}
类ThreadChild1扩展了线程{
私营部门已通知;
公开募捐{
已同步(此){
对于(int i=1;i<10;i++){
System.out.println(“子项”+i);
}
haveNotified=true;
this.notify();
}
}
}

您的代码是错误的,原因是您提到了自己:您无法确定哪个线程先运行。 还有其他可能出错的事情-
等待
可以在没有
通知的情况下醒来

您可以在中阅读,这也解释了您应该做什么:

在单参数版本中,中断和虚假唤醒是非常重要的 可能,并且此方法应始终在循环中使用:

synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
     ... // Perform action appropriate to condition
 }
synchronized(obj){
而()
obj.wait();
…//执行适合条件的操作
}
在您的代码中,您可以使用表示条件“我已收到通知”的布尔变量来解决此问题:

公共类线程示例1{
公共静态void main(字符串[]args)引发InterruptedException{
ThreadChild1 lockingObj=新的ThreadChild1();
lockingbj.start();
已同步(锁定对象){
对于(int i=1;i<10;i++){
系统输出打印项次(“主”+i);
}
而(!lockingbj.haveNotified){
lockingbj.wait();
}
System.out.println(“主收到通知”);
}
}
}
类ThreadChild1扩展了线程{
私营部门已通知;
公开募捐{
已同步(此){
对于(int i=1;i<10;i++){
System.out.println(“子项”+i);
}
haveNotified=true;
this.notify();
}
}
}

虽然这在您的系统上正常工作,但这并不是保证,因为您的怀疑可能在不同的系统上变为真实。线程行为非常难以/不可能预测。因此,我喜欢在最坏的情况下思考,如果我能想出一个可能的中断情况(正如您刚才描述的那样)我只是重新设计,以确保它将工作

测试代码的一个好方法是在关键时刻挂起/暂停线程,方法是在IDE中添加一个断点,如果可能的话添加一个非常耗时的任务/调用(不是故障保护),或者直接暂停线程(并不总是理想的)。此外,我确信有库可以扩展这种类型的测试


我希望这能帮助您朝着正确的方向发展。

虽然这在您的系统上正常工作,但这并不是一个保证,因为您的怀疑可能在另一个系统上变为真实。线程行为很难/不可能预测。因此,我喜欢在最坏的情况下思考,如果我能想出一个可能的破坏性情况,我会n(正如你刚才描述的那样)我只是重新设计以确保它能工作

测试代码的一个好方法是在关键时刻挂起/暂停线程,方法是在IDE中添加一个断点,如果可能的话添加一个非常耗时的任务/调用(不是故障保护),或者直接暂停线程(并不总是理想的)。此外,我确信有库可以扩展这种类型的测试


我希望这能帮助您朝正确的方向发展。

谢谢n247s。我正试图根据您的建议进行测试。我理解。线程行为确实很难预测,这就是我可能会感到困惑的原因。谢谢n247s。我正试图根据您的建议进行测试。我理解。线程行为确实很难预测这就是为什么我可能会感到困惑的原因。