繁体   English   中英

Java同步等待和通知方法

[英]Java synchronization wait and notify methods

我是同步的新手,试图了解等待和通知的工作原理。

题:-

程序同时执行2个线程-T1和T2,但基于输出T1首先运行,执行问题(first)方法,打印问题,设置标志(true),运行notify()方法,执行问题(第二)方法并输入等待方法。 现在,T2启动并执行。

  1. 为什么T2直到T1调用对象聊天的wait方法后才开始。
  2. 第一次执行问题方法并调用notify()方法时,聊天对象上没有wait()(因为t2尚未启动)。 因此,哪个线程侦听此notify方法。

我的代码:

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

结果:-

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!

为什么T2直到T1调用对象聊天的wait方法后才开始?

您有比赛条件。 两个线程中的任何一个都将首先执行。 由于它们都共享一个单独的Chat实例,它们的方法是synchronized ,因此一个实例将阻塞,直到另一个实例解锁了Chat实例上的监视器为止。

第一次执行问题方法并调用notify()方法时,聊天对象上没有wait() (因为t2尚未启动)。 那么,哪个线程侦听此notify方法?

没有。

1.)为什么直到T1调用对象聊天的wait方法后T2才开始?

实际上T2在此之前开始,但是您没有注意到,因为您没有显示任何日志记录语句。 将System.out放入T2的run方法中,然后运行您的程序几次。 您将看到T2在T1调用wait方法之前开始。 请记住,T2无法进入Chat对象的Answer方法,因为T1在最终调用wait()之前已获得其锁定。

要记住的另一件事是,不能保证启动线程的顺序。 仅仅因为T1.start出现在T2.start之前,并不意味着T1将始终首先启动。 线程调度程序做出决定。

2.)当第一次执行问题方法并调用notify()方法时,聊天对象上没有wait()(因为t2尚未启动)。 因此,哪个线程侦听此notify方法。

-如果没有等待调用,则通知不会影响任何线程。

为什么T2直到T1调用对象聊天的wait方法后才开始。

您有一个相同的对象“ m”,并将其传递给不同的线程,并且存在方法级同步,因此,在“调用”进入question()的那一刻,整个对象将被锁定,直到调用wait()为止,因此answer方法将被封锁。

第一次执行问题方法并调用notify()方法时,聊天对象上没有wait()(因为t2尚未启动)。 因此,哪个线程侦听此notify方法。

notify()第一次没有意义,同步方法必须完成所有操作。 如前所述,直到question()完​​成/释放锁后才执行answer()(调用wait())

暂无
暂无

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

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