Java多线程(四)Lock & Condition实现生产者-
2019-10-11 本文已影响0人
GIT提交不上
一、Condition接口
Condition是一个多线程间协调通信的工具类,使得某个或某些线程一起等待某个条件(Condition),只有当该条件具备(signal 或者 signalAll方法被调用)时 ,这些等待线程才会被唤醒,从而重新争夺锁。Condition接口源码如下所示:
图1-1 Condition接口方法.png条件变量Condition需要与锁绑定,多个Condition可以绑定到同一锁上,可通过Lock.newCondition()获取条件变量Condition(实现类AbstractQueuedSynchronizer)。其简单用法如下所示:
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
二、生产者 & 消费者实例
DataBuffer库存存储类如下所示:
public class DataBuffer {
private final Lock lock;
private final Condition notFull;
private final Condition notEmpty;
private int maxSize;
private List<String> storage;
DataBuffer(int size) {
lock = new ReentrantLock();
notFull = lock.newCondition();
notEmpty = lock.newCondition();
maxSize = size;
storage = new LinkedList<>();
}
public void put() {
lock.lock();
try {
while (storage.size() == maxSize) {
System.out.println("队列已满,请等待!");
notFull.await();
}
storage.add("hello" + Math.random());
System.out.println("已经生产1个产品,库存为:" + storage.size());
Thread.sleep(1000);
notEmpty.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void take() {
lock.lock();
try {
while (storage.size() == 0) {
System.out.println("队列为空,请等待!");
notEmpty.await();
}
storage.remove(0);
System.out.println("已消费一个产品,库存为:" + storage.size());
Thread.sleep(1000);
notFull.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
生产者Producer类如下所示:
public class Producer implements Runnable {
private volatile boolean flag = true;
private DataBuffer buffer;
public Producer(DataBuffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
while (flag) {
buffer.put();
}
}
}
消费者Consumer类如下所示:
public class Consumer implements Runnable {
private DataBuffer buffer;
private volatile boolean flag = true;
public Consumer(DataBuffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
while (flag) {
buffer.take();
}
}
}
测试类如下所示:
public class Test {
public static void main(String[] args) {
DataBuffer buffer = new DataBuffer(10);
Consumer consumer = new Consumer(buffer);
Producer producer = new Producer(buffer);
Thread t1 = new Thread(consumer);
Thread t2 = new Thread(producer);
t1.start();
t2.start();
}
}