关于wait和notify的用法,网上已经有很多详细解释了,我只是简单的总结下。
- wait用于释放锁A,并让wait所在的线程阻塞。除非被持有锁A的其它线程执行notify来唤醒,它才能重新"活"过来。
- notify用于唤醒因为等待锁A而阻塞的线程,让它们做好竞争锁A的准备。如果有多个线程因等待锁A而被阻塞,notify只唤醒一个,唤醒所有用notifyAll。
- 参考下面的线程状态图,对理解wait和notify有很大的帮助。
总结:
- wait和notify通常和synchronized(obj)一起用,注意obj应该是多线程共用的同一个对象(即多线程状态下各个线程要竞争这个对象锁),如果不是同一个对象,那么就不能控制并发了,wait和notify也不能有效的相互作用,因为根本就不是操作同一个对象。可以参考文章最后的Demo样例。
- wait和notify来自synchronized中的obj,而不是别的地方,obj只是作为一个对象锁,供各个线程竞争。
--------------------------------
线程状态图(一样的东西,只是中英文描述而已):
--------------------------------
最后上生产/消费模型的代码:
基类
public abstract class Person implements Runnable{
public static Object lock = new Object();
public static int ticket = 0;
public abstract void execute();
}
---
生产者
public class Producer extends Person {
@Override
public void execute() {
synchronized (lock) {
while (true){
if (ticket == 0) {
while(ticket<10) {
System.out.println("生产中,当前数量:"+ticket);
ticket++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产完毕,当前数量:"+ticket);
lock.notify();
}else{
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
@Override
public void run() {
execute();
}
}
---
消费者
public class Consumer extends Person {
@Override
public void execute() {
synchronized (lock){
while (true){
if(ticket==0){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("消耗中,总数量:"+ticket);
while (ticket>0){
System.out.println("消耗中,当前数量:"+ticket);
ticket--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消耗完成,当前数量:"+ticket);
lock.notify();
}
}
}
}
@Override
public void run() {
execute();
}
}
---
运行Demo
public class Demo {
public static void main(String[] args){
//设置先生产还是先消费,默认ticket是0先生产。
//ticket是静态的,所以可以这么设置,虽然不是很规范。
new Producer().ticket = 6;
Thread pro = new Thread(new Producer());
Thread con = new Thread(new Consumer());
pro.start();
con.start();
}
}
重要的事再提一遍:
总结:
- wait和notify通常和synchronized(obj)一起用,注意obj应该是多线程共用的同一个对象(即多线程状态下各个线程要竞争这个对象锁),如果不是同一个对象,那么就不能控制并发了,wait和notify也不能有效的相互作用,因为根本就不是操作同一个对象。可以参考文章最后的Demo样例。
- wait和notify来自synchronized中的obj,而不是别的地方,obj只是作为一个对象锁,供各个线程竞争。
-----------------------------------------------------
请尊重作者劳动成果,
转载请注明出处