阻塞队列 用在哪?
- 生产者消费者模式
传统版
阻塞队列版 - 线程池
- 消息中间件
1、传统线程生产者-消费者模式是什么?
2、传统生产者-消费者模式代码验证2.0版本
判断使用while不会出现虚假唤醒问题
/**
* Lock 传统生产者-消费者模式 代码验证2.0版本
* @Author: 小海
* @Description:
* @Date: Create in 20:03 2020-02-01
*/
public class ShareData {
private int num = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
/**
* 加法操作+1
*/
public void increment(){
lock.lock();
try {
// 防止虚假唤醒机制
while (num != 0){
// if (num != 0){
// 生产者线程等待生产
condition.await();
}
// 生产者线程进行生产操作
num++;
System.out.println(Thread.currentThread().getName() + " " + num);
// 生产者线程通知唤醒消费者线程
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
/**
* 减法操作+1
*/
public void decrement(){
lock.lock();
try {
while (num == 0){
// 消费者线程等待消费
condition.await();
}
// 消费者线程进行消费操作
num--;
System.out.println(Thread.currentThread().getName() + " " + num);
// 消费者线程通知唤醒生产线程
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
/**
* 面试题目:一个初始值为0的变量,两个线程对其交替操作,一个加1,一个减1,交替循环5次
* 传统模式的生产者和消费者Demo
* 1、线程操作资源共享类ShareData
* 2、线程判断(while)是否执行加减操作
* 3、线程操作完成之后,需要通知(condition.signalAll())其他线程
* 4、防止虚假唤醒机制(if和while使用哪个?当然是使用while来判断)
*/
public static void main(String[] args) {
ShareData shareData = new ShareData();
// 线程t1进行加法操作
new Thread(() -> {
for (int i = 0; i < 5; i++) {
shareData.increment();
}
}, "t1").start();
// 线程t2进行减法操作
new Thread(() -> {
for (int i = 0; i < 5; i++) {
shareData.decrement();
}
}, "t2").start();
// 线程t3进行加法操作
new Thread(() -> {
for (int i = 0; i < 5; i++) {
shareData.increment();
}
}, "t3").start();
// 线程t4进行减法操作
new Thread(() -> {
for (int i = 0; i < 5; i++) {
shareData.decrement();
}
}, "t4").start();
}
}