Consider the following scenario: multiple SwingWorkers are executing concurrently, representing various tasks. The requirement is to remove all the associated labels, representing task progress, from the application window once all the tasks have completed.
The challenge lies in ensuring that the label removal is performed only after all SwingWorkers have finished their execution. This is essential to prevent any unnecessary flickering or inconsistent behavior in the UI.
A suitable approach for handling this problem is to employ a CountDownLatch. This construct provides a synchronization mechanism that allows one thread to wait until a specified number of events have occurred. In this specific context, the CountDownLatch is initialized with a count equal to the number of SwingWorkers. Each worker thread is responsible for decrementing the latch count upon completion.
A separate SwingWorker, acting as a "supervisor," is employed to monitor the latch. This supervisor worker blocks on the CountDownLatch.await() method, effectively pausing until all other SwingWorkers have signaled their completion. Once the latch count reaches zero, the supervisor worker proceeds to remove all the labels from the application window.
The following code snippet demonstrates the implementation of this solution:
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(); } }
In this implementation, the CountDownLatch effectively acts as a gatekeeper, ensuring that the label removal is executed only after all SwingWorkers have completed their tasks. This approach promotes a clean and consistent user interface by avoiding unnecessary visual artifacts during asynchronous operations.
The above is the detailed content of How Can CountDownLatch Ensure UI Consistency When Multiple SwingWorkers Finish?. For more information, please follow other related articles on the PHP Chinese website!