前提:一个线程生产,一个线程消费,不能连续生产,不能连续消费 。线程间等待唤醒机制(生产者,消费者)(线程之间的通信)。
案例:生产者生产产品,消费者消费产品。不能连续生产,不能连续消费 。
分析问题:
1、生产者生产产品:定义count++,消费者消费产品:输出count;
2、设置flag,如果为true则有产品,需要消费者消费,生产者等待;如果为false则没有产品,需要消费者等待。
3、加锁来控制线程间的切换,防止在生产和消费时发生线程切换。
4、利用wait和notify方法来保证生产一个消费一个,防止连续生产与消费。
实现:
产品类:
public class Goods {
//代表产品的count
private int count;
//代表是否有产品的flag
private boolean flag;
public Goods() {
}
public Goods (int count, boolean flag) {
this.count = count;
this.flag = flag;
}
/*
getCount 改造成消费产品方法
直接输出count
*/
public void getCount() {
System.out.println("消费了第"+count+"个产品");
}
/*
setCount 改造成生产产品
count++
*/
public void setCount() {
count++;
System.out.println("生产了第"+count+"个产品");
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
生产者:
public class Product implements Runnable{
//这里的有参构造是为了防止加锁时产生锁对象不一致的问题,导致失败
private Goods goods;
public Product(Goods goods) {
this.goods= goods;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (goods){
//1.判断flag是否为true,如果是true,证明有产品,生产线程等待
if (goods.isFlag()==true){
try {
goods.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//2.如果flag为false,证明没有产品,开始生产
goods.setCount();
//3.改变flag状态,为true,证明生产完了,有包子产品
//4.唤醒消费线程
goods.notify();
}
}
}
}
消费者
public class Consumer implements Runnable{
private Goods goods;
public Consumer(Goods goods) {
this.goods= goods;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (goods){
//1.判断flag是否为false,如果是false,证明没有产品,消费线程等待
if (goods.isFlag()==false){
try {
goods.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//2.如果flag为true,证明有产品,开始消费
goods.getCount();
//3.改变flag状态,为false,证明消费完了,没有产品了
goods.setFlag(false);
//4.唤醒生产线程
goods.notify();
}
}
}
}
test类:
public class Test01 {
public static void main(String[] args) {
Goods goods= new Goods ();
//定义一个共有的产品类对象,提供给生产者与消费者产生同一个锁对象。
Product product = new Product(goods);
Consumer consumer = new Consumer(goods);
Thread t1 = new Thread(product);
Thread t2 = new Thread(consumer);
t1.start();
t2.start();
}
}