Java生产者消费者程序线程为何暂停?执行异常排查
问题原因及解决方法
核心问题分析
- 错误调用run方法:main函数中启动线程
t1.start()后,又在while(true)里直接调用t1.run()。start()会创建新线程并由JVM自动调用run方法,而直接调用run()是在main线程中同步执行,导致主线程占用执行权,后续逻辑完全混乱。 - 缺少消费者角色:当前代码只有生产者(Writer),没有对应的消费者(Reader)读取Message中的内容。生产者第一次write后,
empty被设为false,第二次进入write方法时,会因!empty条件进入wait状态,且没有消费者调用read方法唤醒它,程序直接卡住。 - 未实现无限循环打印:Writer的run方法仅遍历一次消息数组就结束,没有循环逻辑,无法达成无限打印的需求。
修正后的完整代码
import java.util.Random; public class Main { public static void main(String[] args) { Message mes = new Message(); // 启动生产者线程 new Writer(mes).start(); // 启动消费者线程 new Reader(mes).start(); } } class Message { private String message; private boolean empty = true; public synchronized String read() { while (empty) { try { wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = true; notifyAll(); return message; } public synchronized void write(String message) { while (!empty) { try { wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = false; notifyAll(); this.message = message; } } class Writer extends Thread { private Message message; public Writer(Message message) { this.message = message; } public void run() { String messages[] = { "Humpty Dumpty sat on a wall", "Humpty Dumpty had a great fall", "All the king's horses and all the king's men", "Couldn't put Humpty together again" }; Random random = new Random(); // 外层循环实现无限打印数组内容 while (true) { for (int i = 0; i < messages.length; i++) { message.write(messages[i]); System.out.println(getName() + ": " + messages[i]); try { Thread.sleep(random.nextInt(2000)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } } } } } class Reader extends Thread { private Message message; public Reader(Message message) { this.message = message; } public void run() { Random random = new Random(); while (true) { String msg = message.read(); System.out.println(getName() + ": " + msg); // 模拟消费耗时 try { Thread.sleep(random.nextInt(2000)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } } } }
关键修改点
- 移除main中的run调用:只保留线程启动的
start()方法,同时新增Reader消费者线程并启动,完善生产者消费者的完整模型。 - 添加无限循环逻辑:在Writer的run方法外层加上
while(true),实现消息数组的循环输出。 - 完善异常处理:捕获InterruptedException时中断当前线程并退出,避免线程无意义挂起。
- 新增消费者实现:Reader类负责读取消息,唤醒等待的生产者,保证生产-消费流程持续循环。
内容的提问来源于stack exchange,提问作者up10388
相关产品推荐
相关产品推荐

