这是一个线程同步问题 , 生产者和消费者共享同一个资源 , 并且生产者和消费者之间相互依赖 , 互为条件。
方法 | 作用 |
---|---|
wait() | 线程会处于等待状态,直到其他线程通知,这个方法会释放锁 |
wait(long timeout) | 指定等待的毫秒 |
notify() | 唤醒一个处于等待状态的线程 |
notifyAll() | 唤醒同一个对象上所有调用wait()方法的线程 , 优先级别高的线程优先调度 |
(1)Productor.java——生产者
package com.pbx.lesson03;
/**
* 生产者
* @author BruceXu
* @date 2020/9/17
*/
public class Productor extends Thread {
private Buffer buffer;
public Productor(Buffer buffer){
this.buffer = buffer;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("生产了第"+i+"只鸡");
buffer.push(new Chicken(i));
// 可以通过修改sleep的时间来模拟不同的生产速度
try {
if (i<10) {
Thread.sleep(100);
} else {
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
(2)Customer.java——消费者
package com.pbx.lesson03;
/**
* 消费者
* @author BruceXu
* @date 2020/9/17
*/
public class Customer extends Thread {
private Buffer buffer;
public Customer(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
Chicken chicken = buffer.pop();
System.out.println("消费了第"+chicken.getId()+"只鸡,现在还有"+buffer.getCount()+"只鸡剩余");
try {
// 可以通过修改sleep的时间来模拟不同的消费
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
(3)Buffer.java——缓冲区
package com.pbx.lesson03;
/**
* 缓冲区
* @author BruceXu
* @date 2020/9/17
*/
public class Buffer {
// 需要一个容器来存放商品
private Chicken[] chickens = new Chicken[10];
// 需要一个计数器
private int count = 0;
public int getCount() {
return count;
}
// 生产者要放入商品
public synchronized void push(Chicken chicken) {
// 如果容器满了,生产者等待,通知消费者消费
if(count >= chickens.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果没满,就可以继续放入商品
chickens[count] = chicken;
count++;
// 通知消费者消费
this.notifyAll();
}
// 消费者要消费商品
public synchronized Chicken pop(){
// 判断能不能消费
if (count==0) {
// 等待生产,等待消费
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 消费
count--;
this.notifyAll();
return chickens[count];
}
}
(4)Chicken.java——商品
package com.pbx.lesson03;
/**
* 商品
*
* @author BruceXu
* @date 2020/9/17
*/
public class Chicken {
private int id;
public int getId() {
return id;
}
public Chicken(int id) {
this.id = id;
}
}
(5)Main.java
package com.pbx.lesson03;
/**
* @author BruceXu
* @date 2020/9/17
*/
public class Main {
public static void main(String[] args) {
Buffer buffer = new Buffer();
new Productor(buffer).start();
new Customer(buffer).start();
}
}
(1)TV.java
package com.pbx.lesson04;
/**
* 看电视
* 节目时间广告等待播放,广告时间节目等待播放
*
* @author BruceXu
* @date 2020/9/18
*/
public class TV {
// 广告时间,false;节目时间,ture
private boolean flag;
public synchronized void playShow(String name) {
// 播放节目之前,先看广告有没有播放过
if (!flag) {
// 没放过广告,那么等待广告播放
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("播放节目:" + name);
// 更改标志位
this.flag = !this.flag;
// 节目放过了,该放广告了
this.notifyAll();
}
public synchronized void playAD(String name) {
// 节目放完了吗?如果没有,就等待节目放完
if (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("播放广告:" + name);
// 更改标志位
this.flag = !this.flag;
// 广告放过了,该放节目了
this.notifyAll();
}
}
(2)AD.java
package com.pbx.lesson04;
/**
* @author BruceXu
* @date 2020/9/18
*/
public class AD extends Thread {
private final TV tv;
public AD(TV tv) {
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
tv.playAD("第" + i + "个广告,今年过节不收礼,收礼只收脑白金");
}
}
}
(3)Show.java
package com.pbx.lesson04;
/**
* @author BruceXu
* @date 2020/9/18
*/
public class Show extends Thread {
private final TV tv;
public Show(TV tv) {
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
tv.playShow("第" + i + "个节目,NBA全明星赛");
}
}
}
(4)Main.java
package com.pbx.lesson04;
/**
* @author BruceXu
* @date 2020/9/18
*/
public class Main {
public static void main(String[] args) {
TV tv = new TV();
new Show(tv).start();
new AD(tv).start();
}
}
原文:https://www.cnblogs.com/primabrucexu/p/13694077.html