版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40646143/article/details/84696273
需要到Object类中的等待与通知的俩个方法如下
notify() | 唤醒正在等待对象监视器的单个线程。 |
notifyAll() | 唤醒正在等待对象监视器的所有线程。 |
wait() | 导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。 |
其中wait()方法和sleep()方法有明显的不同点
共同点是:都可以阻塞线程
不同点: wait()方法会释放锁,而sleep()方法则不会释放锁.
1),首先创建一个公用的场景如下
package com.hp.pro;
/**
* 一个场景一份共同的资源
*
* 生产者消费者模式 信号灯法
*/
public class Film {
private String content;
/**如果 flag 为true 生产者生产 消费者等待 生产完之后通知消费
*如果 flag 为false 消费者消费 生产者等待 消费完之后通知生产
*/
private boolean flag=true;
/**
* 生产
*/
public synchronized void play(String content) throws InterruptedException {
if (!flag){ //生产者等待
this.wait();
}
//开始生产
Thread.sleep(500);
this.content=content;
System.out.println("生产了:" + content);
//通知消费
this.notifyAll();
//生产者停下来
this.flag=false;
}
/**
* 消费
*/
public synchronized void watch() throws InterruptedException {
if (flag){ //消费者等待
this.wait();
}
//开始消费
Thread.sleep(200);
System.out.println("消费了"+content);
//通知生产
this.notifyAll();
//让消费者停止
this.flag=true;
}
}
2),创建生产者
package com.hp.pro;
/**
* 生产者
*/
public class Producer implements Runnable {
private Film film;
public Producer(Film film){
this.film=film;
}
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
if (i%2==0){
try {
film.play("左青龙");
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try {
film.play("右白虎");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
3),创建消费者
package com.hp.pro;
/**
* 消费者
*/
public class Consumer implements Runnable {
private Film film;
public Consumer(Film film){
this.film=film;
}
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
try {
film.watch();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
4),创建运行的类
package com.hp.pro;
public class APP {
public static void main (String[] args) {
Film film1 = new Film();
Producer film = new Producer(film1);
Consumer consumer = new Consumer(film1);
Thread thread1 = new Thread(film);
Thread thread2 = new Thread(consumer);
//开启线程
thread1.start();
thread2.start();
}
}
运行效果如下
总结: notify() /notifyAll() /wait()一定要与Synchronized 同步使用否则就同步不了