简体   繁体   English

Java同步等待和通知方法

[英]Java synchronization wait and notify methods

I'm a newbie to synchronization and trying to understand how wait and notify works. 我是同步的新手,试图了解等待和通知的工作原理。

Question:- 题:-

The programs executes 2 threads - T1 & T2 simultaneously but based on the output T1 runs first, executes the question(first) method, prints the question, sets the flag(true), runs the notify() method, executes the question(second) method & enters the wait method. 程序同时执行2个线程-T1和T2,但基于输出T1首先运行,执行问题(first)方法,打印问题,设置标志(true),运行notify()方法,执行问题(第二)方法并输入等待方法。 Now T2 starts and executes. 现在,T2启动并执行。

  1. Why does T2 doesn't start until T1 calls the wait method of the Object Chat. 为什么T2直到T1调用对象聊天的wait方法后才开始。
  2. When the question method is executed first time and notify() method is called, there is no wait() on the chat object(since t2 did not yet start). 第一次执行问题方法并调用notify()方法时,聊天对象上没有wait()(因为t2尚未启动)。 so, which thread listens to this notify method. 因此,哪个线程侦听此notify方法。

My codes: 我的代码:

package TestThread;

class Chat {
    boolean flag = false;

    public synchronized void Question(String msg) {

        System.out.println("Question method = " + flag);
        if (flag) {
            try {
                System.out.println("Question method wait start");
                wait();
                System.out.println("Question method wait finish");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(msg);
        flag = true;
        notify();
    }

    public synchronized void Answer(String msg) {
        System.out.println("Answer method = " + flag);
        if (!flag) {
            try {
                System.out.println("Answer method wait start");
                wait();
                System.out.println("Answer method wait finish");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println(msg);
        flag = false;
        notify();
    }
}

class T1 implements Runnable {
    Chat m;
    String[] s1 = { "Hi", "How are you ?", "I am also doing fine!" };

    public T1(Chat m1) {
        this.m = m1;
        new Thread(this, "Question").start();
    }

    public void run() {
        for (int i = 0; i < s1.length; i++) {
            m.Question(s1[i]);
        }
    }
}

class T2 implements Runnable {
    Chat m;
    String[] s2 = { "Hi", "I am good, what about you?", "Great!" };

    public T2(Chat m2) {
        this.m = m2;
        new Thread(this, "Answer").start();
    }

    public void run() {
        for (int i = 0; i < s2.length; i++) {
            m.Answer(s2[i]);
        }
    }
}

public class MultiThread {
    public static void main(String[] args) {
        Chat m = new Chat();
        new T1(m);
        new T2(m);            
    }
}

Result:- 结果:-

Question method = false
Hi
Question method = true
Question method wait start
Answer method = true
Hi
Answer method = false
Answer method wait start
Question method wait finish
How are you ?
Question method = true
Question method wait start
Answer method wait finish
I am good, what about you?
Answer method = false
Answer method wait start
Question method wait finish
I am also doing fine!
Answer method wait finish
Great!

Why does T2 doesn't start until T1 calls the wait method of the Object Chat? 为什么T2直到T1调用对象聊天的wait方法后才开始?

You've got a race condition. 您有比赛条件。 Either of the two threads will execute first. 两个线程中的任何一个都将首先执行。 Since they both share a single Chat instance, whose methods are synchronized , one will block until the other has unlocked the monitor on the Chat instance. 由于它们都共享一个单独的Chat实例,它们的方法是synchronized ,因此一个实例将阻塞,直到另一个实例解锁了Chat实例上的监视器为止。

When the question method is executed first time and notify() method is called, there is no wait() on the chat object(since t2 did not yet start). 第一次执行问题方法并调用notify()方法时,聊天对象上没有wait() (因为t2尚未启动)。 so, which thread listens to this notify method? 那么,哪个线程侦听此notify方法?

None do. 没有。

1.) Why does T2 doesn't start until T1 calls the wait method of the Object Chat? 1.)为什么直到T1调用对象聊天的wait方法后T2才开始?

Actually T2 starts before that but you don't notice because you don't have any logging statements to show up. 实际上T2在此之前开始,但是您没有注意到,因为您没有显示任何日志记录语句。 Put a System.out inside run method of T2 and run your program a few times. 将System.out放入T2的run方法中,然后运行您的程序几次。 You will see T2 starting before T1 calls wait method. 您将看到T2在T1调用wait方法之前开始。 Keep in mind T2 cannot enter the Chat object's Answer method since its lock is acquired by T1 before wait() is eventually called. 请记住,T2无法进入Chat对象的Answer方法,因为T1在最终调用wait()之前已获得其锁定。

Another thing to keep in mind is that there is no guarantee of the order in which threads will be started. 要记住的另一件事是,不能保证启动线程的顺序。 Just because T1.start appears before T2.start , does not mean T1 will always be started first. 仅仅因为T1.start出现在T2.start之前,并不意味着T1将始终首先启动。 Thread scheduler makes that decision. 线程调度程序做出决定。

2.)When the question method is executed first time and notify() method is called, there is no wait() on the chat object(since t2 did not yet start). 2.)当第一次执行问题方法并调用notify()方法时,聊天对象上没有wait()(因为t2尚未启动)。 so, which thread listens to this notify method. 因此,哪个线程侦听此notify方法。

--If there has been no wait calls , then notify won't impact any threads. -如果没有等待调用,则通知不会影响任何线程。

Why does T2 doesn't start until T1 calls the wait method of the Object Chat. 为什么T2直到T1调用对象聊天的wait方法后才开始。

You have a same object 'm' and passed it to different threads and there is method level synchronization , so the moment a 'call' enters the question() there will be lock on whole object till wait() is called Hence answer method will be blocked. 您有一个相同的对象“ m”,并将其传递给不同的线程,并且存在方法级同步,因此,在“调用”进入question()的那一刻,整个对象将被锁定,直到调用wait()为止,因此answer方法将被封锁。

When the question method is executed first time and notify() method is called, there is no wait() on the chat object(since t2 did not yet start). 第一次执行问题方法并调用notify()方法时,聊天对象上没有wait()(因为t2尚未启动)。 so, which thread listens to this notify method. 因此,哪个线程侦听此notify方法。

notify() has no significance for the first time, synchronized method has to finish thats all. notify()第一次没有意义,同步方法必须完成所有操作。 as said earlier answer() is not executed till the question() finishes / releases the lock (calling wait()) 如前所述,直到question()完​​成/释放锁后才执行answer()(调用wait())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM