You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

  1. 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.
  2. Infinite Loop with Broken Condition: Your while (i < i + 1) condition is always true (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).
  3. 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 ObservableList with 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_number is accessed safely across threads (since it's read in the background thread and updated in the FX Application Thread). Marking it as volatile would help here too.

内容的提问来源于stack exchange,提问作者Bardh Krasniqi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:05:17