传统版 package com.example.demo; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class ShareData // 资源类 { private int number = 0; private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void increment() throws Exception{ lock.lock(); try { // 1判断 while (number != 0){ // 等待,不能生产 condition.await(); } // 2干活 number++; System.out.println(Thread.currentThread().getName()+"\t"+number); // 3通知唤醒 condition.signalAll(); } catch (Exception e){ e.printStackTrace(); } finally { lock.unlock(); } } public void decrement() throws Exception{ lock.lock(); try { // 1判断 while (number == 0){ // 等待,不能消费 condition.await(); } // 2干活 number--; System.out.println(Thread.currentThread().getName()+"\t"+number); // 3通知唤醒 condition.signalAll(); } catch (Exception e){ e.printStackTrace(); } finally { lock.unlock(); } } } /** * @author chenxf * @create 2021-08-02 21:51 * 一个初始值为0的变量,两个线程对其进行交替操作,一个加1一个减1,来5轮 * * 1 线程 操作 资源类 * 2 判断 干活 通知 * 3 防止虚假唤醒机制 */ 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(); } } },"AAA").start(); new Thread(()->{ for (int i = 1; i <= 5; i++){ try { shareData.decrement(); } catch (Exception e) { e.printStackTrace(); } } },"BBB").start(); } }
阻塞队列版
package com.example.demo; import org.omg.PortableServer.THREAD_POLICY_ID; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; class MyResource{ private volatile boolean FLAG = true; // 默认开启,进行生产+消费 private AtomicInteger atomicInteger = new AtomicInteger(); BlockingQueue<String> blockingQueue = null; public MyResource(BlockingQueue<String> blockingQueue){ this.blockingQueue = blockingQueue; System.out.println(blockingQueue.getClass().getName()); } public void myProd()throws Exception{ String data = null; boolean retValue; while(FLAG){ data = atomicInteger.incrementAndGet()+""; retValue = blockingQueue.offer(data, 2L, TimeUnit.SECONDS); if(retValue){ System.out.println(Thread.currentThread().getName()+"\t 插入队列" + data + "成功"); }else{ System.out.println(Thread.currentThread().getName()+"\t 插入队列" + data + "失败"); } TimeUnit.SECONDS.sleep(1); } System.out.println(Thread.currentThread().getName()+"\t大老板叫停了,表示FLAG=false,生产动作结束"); } public void myConsumer()throws Exception{ String result = null; boolean retValue; while(FLAG){ result = blockingQueue.poll(2L, TimeUnit.SECONDS); if(null == result || result.equals("")){ FLAG = false; System.out.println(Thread.currentThread().getName()+"\t 超过2秒钟没有取到蛋糕,消费退出"); System.out.println(); System.out.println(); return ; } System.out.println(Thread.currentThread().getName()+"\t 消费队列" + result + "成功"); } } public void stop()throws Exception{ this.FLAG = false; } } /** * @author chenxf * @create 2021-08-04 22:51 * * volatile/CAS/atomicInteger/BlockQueue/线程交互/原子引用 */ public class ProdConsumer_BlockQueueDemo { public static void main(String[] args) throws Exception{ MyResource myResource = new MyResource(new ArrayBlockingQueue<>(10)); new Thread(()->{ System.out.println(Thread.currentThread().getName()+"\t 生产线程启动"); try{ myResource.myProd(); }catch (Exception e){ e.printStackTrace(); } },"Prod").start(); new Thread(()->{ System.out.println(Thread.currentThread().getName()+"\t 消费线程启动"); try{ myResource.myConsumer(); System.out.println(); System.out.println(); }catch (Exception e){ e.printStackTrace(); } },"Consumer").start(); // 暂停一会儿线程 try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(); System.out.println(); System.out.println(); System.out.println("5秒钟时间到,大老板main线程叫停,活动结束"); myResource.stop(); } }