Pertimbangkan senario berikut: berbilang SwingWorkers sedang melaksanakan secara serentak, mewakili pelbagai tugas. Keperluan adalah untuk mengalih keluar semua label yang berkaitan, yang mewakili kemajuan tugasan, daripada tetingkap aplikasi setelah semua tugasan selesai.
Cabarannya terletak pada memastikan penyingkiran label dilakukan hanya selepas semua SwingWorkers selesai melaksanakannya . Ini penting untuk mengelakkan sebarang kelipan yang tidak perlu atau tingkah laku tidak konsisten dalam UI.
Pendekatan yang sesuai untuk menangani masalah ini ialah menggunakan CountDownLatch. Konstruk ini menyediakan mekanisme penyegerakan yang membenarkan satu utas menunggu sehingga bilangan peristiwa tertentu telah berlaku. Dalam konteks khusus ini, CountDownLatch dimulakan dengan kiraan yang sama dengan bilangan SwingWorkers. Setiap rangkaian pekerja bertanggungjawab untuk mengurangkan kiraan selak setelah selesai.
SwingWorker yang berasingan, bertindak sebagai "penyelia," digunakan untuk memantau selak. Pekerja penyelia ini menyekat kaedah CountDownLatch.await(), dengan berkesan menjeda sehingga semua SwingWorkers lain telah memberi isyarat bahawa mereka telah selesai. Setelah kiraan selak mencapai sifar, pekerja penyelia terus mengalih keluar semua label daripada tetingkap aplikasi.
Coretan kod berikut menunjukkan pelaksanaan penyelesaian ini:
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(); } }
Dalam pelaksanaan ini, CountDownLatch berkesan bertindak sebagai penjaga pintu, memastikan bahawa label penyingkiran dilaksanakan hanya selepas semua SwingWorkers menyelesaikan tugas mereka. Pendekatan ini menggalakkan antara muka pengguna yang bersih dan konsisten dengan mengelakkan artifak visual yang tidak diperlukan semasa operasi tak segerak.
Atas ialah kandungan terperinci Bagaimanakah CountDownLatch Memastikan Konsistensi UI Apabila Berbilang SwingWorkers Selesai?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!