Java多线程实现生产者消费者问题消费者线程不运行问题排查
问题原因
- 生产者线程、消费者线程各自在
run()方法内部创建了独立的fun类实例,二者操作的不是同一个队列,也没有共享同一把对象锁:- 生产者写入的是自己实例的队列,消费者监听的是自己实例的空队列,永远不会收到可消费的通知
synchronized修饰的非静态方法锁属于当前类实例,两个实例的锁完全隔离,生产者调用的notify()无法唤醒在另一个实例上wait()的消费者线程
修复步骤
- 改造线程类的构造方法,支持外部传入共享的
fun实例,禁止线程内部自行创建实例:
class a extends Thread { private fun obj; // 构造方法传入共享的fun实例 public a(fun obj) { this.obj = obj; } public void run() { try { obj.produce(); } catch(InterruptedException e) { System.out.println(e); } } }
class b extends Thread { private fun obj; // 构造方法传入共享的fun实例 public b(fun obj) { this.obj = obj; } public void run() { try { obj.consume(); } catch(InterruptedException e) { System.out.println(e); } } }
- 改造主类逻辑,先创建全局唯一的
fun实例,再传入两个线程:
class pcp { public static void main(String[]args) throws InterruptedException { // 先创建全局共享的fun实例 fun sharedObj = new fun(); // 把同一个实例传给两个线程 a t1=new a(sharedObj); b t2=new b(sharedObj); t1.start(); System.out.println(t1.isAlive()); t2.start(); System.out.println(t1.isAlive()); t1.join(); t2.join(); } }
附加优化建议
- Java编码规范要求类名首字母大写,建议将
fun、a、b、pcp调整为语义更清晰、符合规范的命名,比如SharedQueue、ProducerThread、ConsumerThread、ProducerConsumerDemo,提升代码可读性。
内容的提问来源于stack exchange,提问作者Srinivas
相关产品推荐
相关产品推荐

