【问题标题】:Listeners and threads侦听器和线程
【发布时间】:2026-02-07 20:25:01
【问题描述】:

我觉得这可能是一个愚蠢的问题,但我对听众的经验并不丰富......无论如何,我有一个关于线程和听众的问题;考虑一下这段代码(可能在语法上不正确,这样做是出于我的想法):

public class Stuff {
    private SimpleLongProperty time = new LongProperty(this, "time");
    private Executor execute;

    public Stuff(Clock clock) {
        time.bind(clock.getValue);
        execute = Executors.newFixedThreadPool(5);
    }

    public void someAction() {
        for(int i = 0; i < 5; i++) {
            execute.execute(scheduleTask());
        }
    }

    public Runnable scheduleTask() {
        time.addListener((obs, oldV, newV) -> {
            //Code here
        });
    }
}

当调用 someAction() 并调用 scheduleTask() 5 次以添加 5 个侦听器时,每个侦听器会在时间更新时在自己的线程中执行代码吗?还是会在主线程中执行代码,因为那是时间所在?

【问题讨论】:

  • 监听器将从调用它们的线程上下文中调用(在这种情况下为执行器线程)
  • “代码可能在语法上不正确,这是我的头顶上的事情” - 下次当您提供可以编译的语法正确的最小示例时,您可能会得到更多答案。
  • @J-Alex JUnit 成功案例!
  • 作为答案发布(不是对问题的编辑)并接受它。

标签: java multithreading listener


【解决方案1】:

能够在工作站上编写代码并对其进行测试,找到了我的答案。

public class Stuff {
    private LongProperty time = new SimpleLongProperty(this, "time");
    private Executor execute;

    public Stuff(Clock clock) {
        time.bind(clock.getValue);
        execute = Executors.newCachedThreadPool(runnable -> {
            Thread t = new Thread(runnable);
            t.setDaemon(true);
            return t;
        });
    }

    public void someAction() {
        for(int i = 0; i < 5; i++) {
            execute.execute(scheduleTask(i));
        }
    }

    public Runnable scheduleTask(int i) {
        time.addListener((obs, oldV, newV) -> {
            System.out.println("Task " + i + ": " + Thread.currentThread());
        });
    }
}

上面的代码会有打印:

Task 0: Thread[JavaFX Application Thread, 5, main]
Task 1: Thread[JavaFX Application Thread, 5, main]
Task 2: Thread[JavaFX Application Thread, 5, main]
Task 3: Thread[JavaFX Application Thread, 5, main]
Task 4: Thread[JavaFX Application Thread, 5, main]

把 someAction() 和 scheduleTask() 函数改成这样:

public void someAction() {
    for(int i = 0; i < 5; i++) {
        scheduleTask(i);
    }
}

public void scheduleTask(int i) {
    Runnable test = () -> {
        System.out.println("Task " + i + ": " + Thread.currentThread());
    };
    time.addListener((obs, oldV, newV) -> {
        execute.execute(test);
    });
}

将产生以下结果:

Task 0: Thread[Thread-16, 5, main]
Task 1: Thread[Thread-17, 5, main]
Task 2: Thread[Thread-20, 5, main]
Task 3: Thread[Thread-19, 5, main]
Task 4: Thread[Thread-18, 5, main]

【讨论】: