线程信令序列 [英] Thread Signalling Sequence

查看:73
本文介绍了线程信令序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the below code I have implemented inter Thread communication using wait() -notify() and it is giving me expected output. expected Output : 123456789 Actual output : 123456789

我的问题是,由于线程调度取决于jvm,因此是否可以保证始终使主线程"获得首次执行的机会.如果子线程"获得第一次机会,则notify()信号将丢失,并且主线程"将永远等待.我如何确认主线程"将始终首先执行.另外,请确认是否可以改进以下代码.

My question is , is there any guarantee that always 'Main Thread' will get the first chance to execute, since Thread scheduling depends on jvm. And if 'child thread' gets the first chance, the notify() signal will miss and the 'main Thread ' will wait forever. How can I confirm that 'Main thread' will execute first always. Also please confirm if the below code can be improved.

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();
            }
    }
}

推荐答案

由于您提到自己,您的代码是错误的:您无法确定哪个线程在前. 还有其他可能出错的地方-wait可以在没有notify的情况下唤醒.

Your code is wrong for the reason that you mentioned yourself: you can't be sure which thread goes first. There are other things that could go wrong - wait can wake up without a notify.

您可以在用于wait方法的Javadoc ,该文档还说明了您应该执行的操作:

You can read about it in the Javadoc for the wait method, which also explains what you should do:

与在一个参数版本中一样,中断和虚假唤醒是 可能,并且此方法应始终在循环中使用:

As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:

synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
     ... // Perform action appropriate to condition
 }

在您的代码中,您可以使用一个布尔变量来解决它,该布尔变量表示条件我已收到通知":

In your code, you can solve it with a boolean variable that expresses the condition "I was notified":

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);
            }
            while (!lockingObj.haveNotified) {
                lockingObj.wait();
            }
            System.out.println("Main got notified");
        }

    }

}

class ThreadChild1 extends Thread{
    private boolean haveNotified;
    public void run(){
        synchronized (this) {
            for (int i = 1; i < 10; i++) {
                System.out.println("Child " + i);
            }
            haveNotified = true;
            this.notify();
        }
    }
}

这篇关于线程信令序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆