下面是生产者和消费者的代码
ReentranLock 使用Condition 的 await, signal, signalAll
来代替 Synchronized 中的 wait,notify,notifyAll
,两者都要 在 代码块里面使用
package app;
import java.util.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Author lyr
* @create 2019/9/30 0:28
*/
public class Main {
public static void main(String[] args) {
Shop shop = new Shop(30);
Producer producer = new Producer(shop);
Consumer consumer = new Consumer(shop);
for(int i=0;i<2;++i)
{
new Thread(consumer,"消费者: "+i).start();
}
for(int i=0;i<4;++i)
{
new Thread(producer,"生产者: "+i).start();
}
}
static class Shop {
private final Lock lock;
private final Condition producerCondition;
private final Condition consumerCondition;
private int maxSize;
private List<Integer> storage;
Shop(int size){
//使用锁lock,并且创建两个condition,相当于两个阻塞队列
lock=new ReentrantLock();
producerCondition =lock.newCondition();
consumerCondition =lock.newCondition();
maxSize=size;
storage=new LinkedList<>();
}
public void produce() {
lock.lock();
try {
while (storage.size() ==maxSize ){//如果队列满了
System.out.print(Thread.currentThread().getName()+": 太多货了,停止生产 \n");;
producerCondition.await();//阻塞生产线程
}
storage.add((int) (Math.random()*101));
System.out.print(Thread.currentThread().getName()+": 生产了,库存为:"+storage.size()+ "\n");
Thread.sleep(1000);
consumerCondition.signalAll();//唤醒消费线程
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
lock.unlock();
}
}
public void consume() {
lock.lock();
try {
//避免虚假唤醒,要循环判断
while (storage.size() ==0 ){//如果队列满了
System.out.print(Thread.currentThread().getName()+": 买完了 --等待生产 \n");;
consumerCondition.await();//阻塞消费线程
}
Integer d=((LinkedList<Integer>)storage).poll();
System.out.print(Thread.currentThread().getName()+": 消费了:"+storage.size()+ "\n");
Thread.sleep(3000);
producerCondition.signalAll();//唤醒生产线程
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
lock.unlock();
}
}
}
static class Producer implements Runnable{
private Shop shop;
Producer(Shop b){
shop =b;
}
@Override
public void run() {
while(true){
shop.produce();
}
}
}
static class Consumer implements Runnable{
private Shop shop;
Consumer(Shop b){
shop =b;
}
@Override
public void run() {
while(true){
shop.consume();
}
}
}
//---------------------------------------------------------
}