JavaFX多线程创建问题:实时刷新列表出现重复通知
Fixing Duplicate Notifications & Thread Leaks in JavaFX Real-Time List Refresh
Let's break down the issues in your current code and walk through how to fix them:
Key Problems Identified
- Uncontrolled Thread Spawning: Every time your view initializes, you start a new thread without stopping any existing ones from previous view instances. This leads to multiple threads running the same check logic, hence duplicate refresh notifications.
- Infinite Loop with Broken Condition: Your
while (i < i + 1)condition is alwaystrue(since any integer plus 1 is larger than itself). This means threads will run indefinitely even after the view is closed (daemon threads only exit when the entire JVM shuts down, not when your view is destroyed). - Missing Thread Termination: There's no mechanism to stop the thread when the view is closed, causing thread leaks and unnecessary resource usage.
Step-by-Step Solution
1. Add a Thread Termination Flag
First, declare a volatile boolean flag to safely control the thread's loop (volatile ensures visibility across threads):
private volatile boolean isThreadRunning = false; private Thread thread = null;
2. Fix the Thread Logic & Loop Condition
Rewrite your Runnable to use the termination flag instead of the broken i condition. Also, ensure we only start a thread if one isn't already running:
@Override public void initialize() { // Stop existing thread if it's running (in case initialize is called again) if (thread != null && thread.isAlive()) { isThreadRunning = false; try { thread.join(1000); // Wait up to 1 second for the thread to finish } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } isThreadRunning = true; Runnable br = new Runnable() { @Override public void run() { while (isThreadRunning) { try { Thread.sleep(1000); // Check if patient count changed int currentPatientCount = pjc.getPacientForDoctor(doctor_login).size(); if (count_pacient_number != currentPatientCount) { Platform.runLater(() -> { emf.getCache().evictAll(); pacientList.clear(); patientList(); // Assuming this populates pacientList count_pacient_number = currentPatientCount; }); } } catch (InterruptedException ex) { // Reset interrupt status and exit loop Thread.currentThread().interrupt(); break; } } } }; thread = new Thread(br); thread.setDaemon(true); thread.start(); }
3. Stop the Thread When the View Closes
Override the stop() method of your view controller to terminate the thread when the view is closed:
@Override public void stop() throws Exception { super.stop(); isThreadRunning = false; if (thread != null && thread.isAlive()) { thread.interrupt(); // Wake up the thread from sleep if needed thread.join(1000); } }
Additional Notes
- Avoid Polling If Possible: Polling every second works, but for more efficient real-time updates, consider using a publisher-subscriber pattern (e.g., using JavaFX
ObservableListwith listeners, or a message broker if your data comes from a remote source). This eliminates the need for continuous polling threads. - Thread Safety: Ensure
count_pacient_numberis accessed safely across threads (since it's read in the background thread and updated in the FX Application Thread). Marking it asvolatilewould help here too.
内容的提问来源于stack exchange,提问作者Bardh Krasniqi
相关产品推荐
相关产品推荐

