首先,我尝试定义一个包含2个同步方法的类,第一个包含wait()调用,第二个包含notify()调用。
class Xa {
public synchronized void printX() {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("XXX");
}
public synchronized void notifyX() {
System.out.println("111");
notify();
}
}
然后我尝试在main中创建两个线程,第一个线程调用Xa类的对象的printX()方法,第二个线程调用同一对象的notifyX()方法,最后是main线程连接两个线程。
我用 for 循环重复这个场景
public class TryQ {
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread t1 = null;
Thread t2 = null;
for(int i=1 ; i<=100; i++) {
Xa x = new Xa();
t1 = new Thread() {
@Override
public void run() {
x.printX();
}
};
t2 = new Thread() {
@Override
public void run() {
x.notifyX();
}
};
t1.start();
t2.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
问题是,如果没有加入,第一个和第二个线程都会准确打印 100 次,但是当我尝试通过主线程加入它们时,我最多有 2 或 3 行输出......并且程序仍在运行!
为什么?
最佳答案
无论您是否使用join
,问题都存在。
问题是,如果t2
先执行notifyX
,
public synchronized void notifyX() {
System.out.println("111");
notify();
}
然后t1
调用printX
,t1
将永远被阻塞!
public synchronized void printX() {
try {
wait(); <--- since t2 has finished, t1 will get stuck here!
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("XXX");
}
区别在于:
- 如果没有
join
,尽管第一个t1
被卡住,但主线程将创建一个新的t1
并运行。 - 使用
join
,由于第一个t1
卡住了,所以join
会阻塞主线程,所以不会有下一代.
关于java - 在调用 wait 和 notification 之后,我尝试从主线程加入两个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54375416/