多生产者多消费者,生产一个数据,消费一个数据
方式一
/** * 多个线程要操作的数据index , 要放再同步块里,这里是放在lock的同步块代码里了,但是对数据的增加和减少放在了Producer类和Consumer类了,没有体现内聚性 */ public class Test { private Object lock = new Object(); private volatile boolean isProduced = false; private int index = 0; public static void main(String[] args) { Test test = new Test(); new Thread(test.new Producer(), "P1").start(); new Thread(test.new Producer(), "P2").start(); new Thread(test.new Consumer(), "C1").start(); new Thread(test.new Consumer(), "C2").start(); new Thread(test.new Consumer(), "C3").start(); } class Producer implements Runnable { @Override public void run() { while (true) { synchronized (lock) { while (isProduced) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } index++; System.out.println(Thread.currentThread().getName() + " 生产数据 " + index); isProduced = true; lock.notifyAll(); } try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class Consumer implements Runnable { @Override public void run() { while (true) { synchronized (lock) { while (!isProduced) { try { lock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + " 消费数据 " + index); isProduced = false; lock.notifyAll(); } try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
方式二
/** * * 多个线程要操作的数据i要放在同步块里,这里是lock锁的同步块里了,对数据i的操作与数据i放在同一个类里了,体现了内聚性 * */ public class Test2{ private int i = 0; final private Object LOCK = new Object(); private volatile boolean isProduced = false; public void produce() { synchronized (LOCK) { while (isProduced) { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } i++; System.out.println(Thread.currentThread().getName() + " 生产 了 " + i); LOCK.notifyAll(); isProduced = true; } } public void consume() { synchronized (LOCK) { while (!isProduced) { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() +" 消费了 " + i); LOCK.notifyAll(); isProduced = false; } } public static void main(String[] args) { Test2 pc = new Test2(); Stream.of("P1", "P2", "P3").forEach(n -> new Thread(n) { @Override public void run() { while (true) { pc.produce(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start() ); Stream.of("C1", "C2", "C3", "C4").forEach(n -> new Thread(n) { @Override public void run() { while (true) { pc.consume(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start() ); } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用