/**
* @ClassName ProdConsumer_TraditionDemo
* @Description 模拟生产者消费者模式
*
* 让两个线程对一个初始变量0,一个加1一个减1 模拟生产者消费者
*
* 1 线程 操作 资源类
* 2 判断 干活 通知
* 3 防止虚假唤醒机制
**/
// 资源类
class ShareData{
private int number = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
//加温度/生产
public void increment() throws Exception{
lock.lock();
try{
// 判断
//使用while不使用if的原因是,if在只有两个线程的时候没有问题,一个唤醒另一个必然满足判断
//条件往下执行,但是当有多个线程大于2的时候比如有两个消费者线程都在等待那么一旦唤醒
//两个线程都会往下走那么就会产生并发问题,而使用while在唤醒时 while会再去判断一次
//是否满足
while(number != 0){
// 等待 不能生产
condition.await();
}
// 干活
number++;
System.out.println(Thread.currentThread().getName() + "\t" + number);
// 通知唤醒
condition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
//减温度/消费
public void decrement() throws Exception{
lock.lock();
try{
// 判断
while(number == 0){
// 等待 不能生产
condition.await();
}
// 干活
number--;
System.out.println(Thread.currentThread().getName() + "\t" + number);
// 通知唤醒
condition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
public class ProdConsumer_TraditionDemo {
public static void main(String[] args) {
ShareData shareData = new ShareData();
new Thread(() ->{
for (int i = 1; i <= 5; i++) {
try {
shareData.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"AA").start();
new Thread(() ->{
for (int i = 1; i <= 5; i++) {
try {
shareData.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"BB").start();
}
}
生产者消费者ReentrantLock+Condition的传统实现demo
最新推荐文章于 2022-08-03 19:52:33 发布