【发布时间】:2015-11-03 20:45:18
【问题描述】:
当用户在 TextField 中输入时:我需要通过 WebRequest 搜索一些数据并显示出来。
当用户输入多个字符时,应取消之前的下载并开始新的下载。
所以我使用一个任务来下载数据,并在任务返回数据时使用一个服务来显示数据。
s = new Service(){
@Override
protected Task createTask() {
return new Task<String>(){
@Override
protected String call() throws Exception {
//DOWNLOAD DATA
System.out.println("1");
Thread.sleep(1000);
System.out.println("2");
Thread.sleep(1000);
System.out.println("3");
Thread.sleep(1000);
return "banana";
}
};
}
};
s.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
@Override
public void handle(WorkerStateEvent event) {
System.out.println(event.getSource().getValue() + " DISPLAYED");
}
});
//HANDLE KEY RELEASED ON A TEXTFIELD
public void onTextFieldKeyReleased() {
s.restart();
}
我注意到每次重新启动服务时都会出现另一个线程,直到出现一定数量的线程。 这使得程序显示数据有很大的延迟。
当 KeyReleasedEvent 发生时,我希望服务执行的操作是取消当前正在运行的任务并开始一个新任务……而不是每次都附加一个新任务。
我怎样才能做到这一点?
【问题讨论】:
-
我无法用您发布的代码重现“巨大延迟”。你能创建一个minimal reproducible example吗?
-
@James_D 也许您无法重现延迟,但您可以看到创建了很多线程,我也不希望这种情况发生。另外,我注意到在打印每个线程之前必须关闭生成的服务,这需要一秒钟,这对我来说太多了。
-
我不明白为什么创建一个新线程会导致问题,但是你读过documentation吗? “在打印每个线程之前必须关闭生成的服务”是什么意思?我不明白。即使您不发布演示延迟的代码,您至少可以使用演示该问题的代码来编辑您的问题吗?
-
@James_D “调用 Thread.sleep() 成本不高,但创建线程可能会。”这就是我使用服务的原因。无论如何......我至少在现在解决了这种情况,ScheduledExecutorService 使用 newSingleThreadScheduledExecutor 初始化。这个执行器不是创建很多线程,而是一次只运行一个线程/
-
我会假设服务的默认执行器缓存线程并尽可能在现有(未使用的)线程上运行新任务(即默认情况下它可能使用缓存的线程池执行器)。无论如何,您有什么实际证据证明它正在创建这么多线程?
标签: java multithreading javafx task java.util.concurrent