[英]Java synchronization wait and notify methods
我是同步的新手,试图了解等待和通知的工作原理。
题:-
程序同时执行2个线程-T1和T2,但基于输出T1首先运行,执行问题(first)方法,打印问题,设置标志(true),运行notify()方法,执行问题(第二)方法并输入等待方法。 现在,T2启动并执行。
我的代码:
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.