考虑以下场景:多个 SwingWorker 并发执行,代表各种任务。要求是在所有任务完成后,从应用程序窗口中删除所有代表任务进度的关联标签。
挑战在于确保仅在所有 SwingWorkers 完成执行后才执行标签删除。这对于防止 UI 中出现任何不必要的闪烁或不一致行为至关重要。
处理此问题的合适方法是使用 CountDownLatch。此构造提供了一种同步机制,允许一个线程等待,直到发生指定数量的事件。在此特定上下文中,CountDownLatch 的初始化计数等于 SwingWorkers 的数量。每个工作线程负责在完成时递减闩锁计数。
使用一个单独的 SwingWorker 充当“主管”来监视闩锁。该主管工作线程阻塞在 CountDownLatch.await() 方法上,有效地暂停,直到所有其他 SwingWorkers 发出完成信号。一旦闩锁计数达到零,主管工作人员就会继续从应用程序窗口中删除所有标签。
以下代码片段演示了此解决方案的实现:
import java.util.concurrent.CountDownLatch; ... private class Supervisor extends SwingWorker<Void, Void> { CountDownLatch latch; public Supervisor(CountDownLatch latch) { this.latch = latch; } @Override protected Void doInBackground() throws Exception { latch.await(); return null; } @Override protected void done() { for (JLabel label : labels) { label.setText("Fin!"); label.setBackground(Color.lightGray); } startButton.setEnabled(true); //panel.removeAll(); panel.revalidate(); panel.repaint(); } } ... private static class Counter extends SwingWorker<Void, Integer> { private JLabel label; CountDownLatch latch; public Counter(JLabel label, CountDownLatch latch) { this.label = label; this.latch = latch; } @Override protected Void doInBackground() throws Exception { int latency = rand.nextInt(42) + 10; for (int i = 1; i <= 100; i++) { publish(i); Thread.sleep(latency); } return null; } @Override protected void process(List<Integer> values) { label.setText(values.get(values.size() - 1).toString()); } @Override protected void done() { label.setBackground(Color.green); latch.countDown(); } }
在此实现中,CountDownLatch 有效地充当看门人,确保仅在所有 SwingWorkers 完成其任务后才执行标签删除。这种方法通过避免异步操作期间不必要的视觉伪影来促进干净且一致的用户界面。
以上是当多个 SwingWorker 完成时,CountDownLatch 如何保证 UI 一致性?的详细内容。更多信息请关注PHP中文网其他相关文章!