如何将Java线程从BLOCKED状态恢复为RUNNABLE状态?
解决多线程弹窗程序的线程阻塞问题
嘿,这个问题我之前整蛊朋友的时候也踩过坑!核心原因是你在**非事件调度线程(EDT)**里直接创建和操作Swing组件——Swing是单线程模型的,所有UI相关的操作必须在EDT中执行,多个线程同时抢着执行UI操作就会触发内部锁,导致除了一个线程外,其他全被阻塞。
问题根源拆解
你的Spam构造函数里,每个线程都在自己的线程循环中直接创建JFrame并调用setVisible(true),这些操作属于UI操作,Swing内部会强制要求这些操作在EDT中执行。当多个线程同时尝试执行这些UI操作时,它们会竞争EDT的执行权限,最终只有一个线程能拿到锁进入RUNNABLE状态,其他线程都被阻塞在BLOCKED状态,自然弹窗速率提不上来。
解决方案:把UI操作交给EDT处理
我们需要让线程只负责生成弹窗的随机参数(位置、颜色),而实际创建窗口、设置属性的UI操作,交给Swing的EDT来执行。可以用SwingUtilities.invokeLater()方法把UI任务提交到EDT的任务队列中,EDT会按顺序处理这些任务,同时你的工作线程可以继续生成新的任务,不会被阻塞。
修改后的代码示例
1. 优化线程类MyThread
import javax.swing.*; import java.awt.*; import java.util.Random; public class MyThread implements Runnable { @Override public void run() { Random r = new Random(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); while (!Thread.currentThread().isInterrupted()) { // 生成随机参数(每个线程有独立Random实例,线程安全) int x = Math.max(0, r.nextInt((int) screenSize.getWidth()) - 100); int y = Math.max(0, r.nextInt((int) screenSize.getHeight()) - 100); Color randomColor = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)); // 把UI操作提交到EDT执行 SwingUtilities.invokeLater(() -> { JFrame window = new JFrame(); window.setSize(100, 100); window.setLocation(x, y); window.setBackground(randomColor); window.setVisible(true); }); // 加微小延迟,避免EDT过载,同时控制弹窗速率 try { Thread.sleep(8); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } } }
2. 主类Init保持不变
import java.util.ArrayList; public class Init { public static void main(String[] args) throws InterruptedException { ArrayList<Thread> list = new ArrayList<>(); for(int i = 0; i < 4; i++) { Thread t = new Thread(new MyThread()); t.start(); list.add(t); } Thread.sleep(1000); for(Thread t : list) { System.out.println(t.getName() + " " + t.getState()); } } }
修改后效果说明
- 现在每个工作线程只负责生成随机参数,然后提交UI任务到EDT,线程本身不会执行任何UI操作,所以不会被阻塞,状态会是
RUNNABLE或者TIMED_WAITING(sleep的时候)。 - EDT会批量处理这些UI任务,弹窗速率会明显提升,因为多个线程同时在生成任务,EDT会尽可能快地处理它们。
- 加了
Math.max(0, x)避免窗口跑到屏幕外,小延迟Thread.sleep(8)可以防止EDT被瞬间塞满导致系统卡顿,你可以根据需要调整这个延迟时间来控制弹窗速度。
内容的提问来源于stack exchange,提问作者Papermage11
相关产品推荐
相关产品推荐

