本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
高内聚低耦合的情况下线程操纵资源类
判断干活唤醒通知
严防多线程并发状态下的虚假唤醒
题目: 一个初始值为零的变量,两个线程对其交替操作,一个加1一个减1,来5轮
线程 操作(方法) 资源类 判断 干活 通知 防止虚假唤醒机制
多线程判断要用while防止虚假唤醒
传统版的生产者消费者模式代码(看注释)
package com.wsx.productConsumer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class shareDate {
private int number = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void increment() {
lock.lock();
try {
//判断
while (number != 0) {
//不能生产
condition.await();
}
//生产
number++;
System.out.println(Thread.currentThread().getName() + "线程 \t" +number+ "生产");
//唤醒
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void decrement() {
lock.lock();
try {
//判断
while (number == 0) {
//不能消费
condition.await();
}
//消费
number--;
System.out.println(Thread.currentThread().getName() + "线程 \t" +number+ "消费");
//唤醒
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class ProductConsumerDemo {
public static void main(String[] args) {
shareDate shareDate = new shareDate();
new Thread(()->{
for (int i = 1; i <= 5 ; i++) {
shareDate.increment();
}
},"AAA").start();
new Thread(()->{
for (int i = 1; i <= 5 ; i++) {
shareDate.decrement();
}
},"BBB").start();
new Thread(()->{
for (int i = 1; i <= 5 ; i++) {
shareDate.increment();
}
},"CCC").start();
new Thread(()->{
for (int i = 1; i <= 5 ; i++) {
shareDate.decrement();
}
},"DDD").start();
}
}
阻塞队列版的生产者消费者模式代码(看注释)
package com.wsx.productConsumer;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
class ProductConsumer {
private volatile boolean FLAG = true;
private AtomicInteger atomicInteger = new AtomicInteger();
private BlockingQueue<String> blockingQueue = null;
public ProductConsumer(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
}
public void increment() throws Exception {
String date = null;
boolean retValue;
while (FLAG) {
date = atomicInteger.incrementAndGet() + "";
retValue = blockingQueue.offer(date, 2L, TimeUnit.SECONDS);
if (retValue) {
System.out.println(Thread.currentThread().getName() + "\t" + date + "生产一个蛋糕");
} else {
System.out.println(Thread.currentThread().getName() + "\t" + date + "生产一个失败");
}
TimeUnit.SECONDS.sleep(1);
}
System.out.println(Thread.currentThread().getName()+"boss暂停不生产了");
}
public void decrement() throws Exception {
String result = null;
while (FLAG) {
result = blockingQueue.poll(2L, TimeUnit.SECONDS);
if(null == result || result.equalsIgnoreCase("")){
FLAG = false;
System.out.println(Thread.currentThread().getName()+"超过两秒没有取出蛋糕暂停");
return;
}
System.out.println(Thread.currentThread().getName()+"消费蛋糕成功");
}
}
public void stop(){
this.FLAG = false;
}
}
public class ProductConsumerBlockingQueue {
public static void main(String[] args){
ProductConsumer productConsumer = new ProductConsumer(new ArrayBlockingQueue<>(10));
new Thread(()->{
try {
System.out.println("生产线程启动");
for (int i = 1; i <= 5 ; i++) {
productConsumer.increment();
}
} catch (Exception e) {
e.printStackTrace();
}
},"prod").start();
new Thread(()->{
try {
System.out.println("消费线程启动");
for (int i = 1; i <= 5 ; i++) {
productConsumer.decrement();
}
} catch (Exception e) {
e.printStackTrace();
}
},"consumer").start();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("boss叫停");
productConsumer.stop();
}
}