Lock实现多生产者-多消费者模型
简单介绍一下Lock:
Lock接口的出现替代了同步代码块或者同步函数,将同步的隐式锁操作变成显式的锁操作;同时也可以更加灵活,可以一个锁上增加多组监视器;
Condition接口的出现代替了Object中的wait(),notify(),notifyAll()方法,将这些监视器方法进行了封装,变成了Condition监视器对象;有方法await(),signal(),signalAll();
为什么要提供监视器对象?
为了实现精准唤醒,只唤醒对方的线程,在进阶版代码中将有所体现;
线程 操作 资源类
判断 干活 通知
防止 虚假 唤醒
基础版本
测试方法
@Test
public void testLock() throws InterruptedException {
Resource resource = new Resource();
Consumer consumerTask = new Consumer(resource);
Producer producerTask = new Producer(resource);
new Thread(consumerTask," A ").start();
new Thread(consumerTask," B ").start();
new Thread(producerTask," C ").start();
new Thread(producerTask," D ").start();
Thread.sleep(10000);
}
资源类
static class Resource {
private int count = 1;
private boolean flag = false;
private String name;
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void set(String name){
lock.lock();
try {
while(flag) {
try { condition.await(); } catch (InterruptedException ignored) {}
}
this.name = name + count;
count++;
System.out.println(Thread.currentThread().getName() + " 生产者 " + this.name);
flag = true;
condition.signalAll();
} finally{
lock.unlock();
}
}
public void out(){
lock.lock();
try {
while(!flag) {
try { condition.await(); } catch (InterruptedException ignored) {}
}
System.out.println(Thread.currentThread().getName() + " 消费者 " + name);
flag = false;
condition.signalAll();
} finally{
lock.unlock();
}
}
}
生产者&消费者
static class Consumer implements Runnable{
private final Resource resource;
public Consumer(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
while(true)
resource.out();
}
}
static class Producer implements Runnable {
private final Resource resource;
public Producer(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
while(true)
resource.set("馒头");
}
}
精准唤醒版本
创建两个监视器,分别监视生产者,消费者,使用这两个监视器可以实现精确唤醒的
资源类
static class ConditionResource {
private int count = 1;
private String name;
private boolean flag = false;
// 锁对象
private final Lock lock = new ReentrantLock(true);
//生产者的监视器
private final Condition proCondition = lock.newCondition();
//消费者的监视器
private final Condition consuCondition = lock.newCondition();
public void set(String name){
lock.lock();
try {
while(flag) {
try { proCondition.await(); } catch (InterruptedException ignored) { }
}
this.name = name + count;
count++;
System.out.println(Thread.currentThread().getName() + " 生产者 " + this.name);
flag = true;
consuCondition.signalAll();
} finally{
lock.unlock();
}
}
public void out() {
lock.lock();
try {
while(!flag) {
try { consuCondition.await();} catch (InterruptedException ignored) { }
}
System.out.println(Thread.currentThread().getName() + " 消费者 " + this.name);
flag = false;
proCondition.signalAll();
} finally{
lock.unlock();
}
}
}
消费者任务类,生产者的任务类:
static class ConsumerCon implements Runnable{
private final ConditionResource resource;
public ConsumerCon(ConditionResource resource) {
this.resource = resource;
}
@Override
public void run() {
while(true)
resource.out();
}
}
static class ProducerCon implements Runnable {
private final ConditionResource resource;
public ProducerCon(ConditionResource resource) {
this.resource = resource;
}
@Override
public void run() {
while(true)
resource.set("馒头");
}
}
欢迎小伙伴评论区交流