我无法重现您提到的延迟。
由于documented,Service
使用“某些默认执行程序”来执行由createTask
方法创建的Task
。您可以配置执行,如果你想修改默认的行为,例如:
s.setExecutor(Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t ;
});
很明显,你可以请根据您的具体要求(这并不完全清楚你的问题),你选择的任何遗嘱执行人。例如,如果你想限制(说)5线程,你可以做
s.setExecutor(Executors.newFixedThreadPool(5, runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t ;
});
这是一个SSCCE。我加了一些记录到跟踪服务的状态,并显示该线程正在使用的任务:
import java.util.concurrent.Executors;
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ServiceRestartTest extends Application {
@Override
public void start(Stage primaryStage) {
Service<Void> s = new Service<Void>(){
@Override
protected Task<Void> createTask() {
return new Task<Void>(){
@Override
protected Void call() throws Exception {
//DOWNLOAD DATA
System.out.println("New task on thread "+Thread.currentThread());
System.out.println("1");
Thread.sleep(1000);
System.out.println("2");
Thread.sleep(1000);
System.out.println("3");
Thread.sleep(1000);
return null;
}
};
}
};
s.setExecutor(Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t;
}));
s.stateProperty().addListener((obs, oldState, newState) -> System.out.println(newState));
TextField textField = new TextField();
textField.setOnKeyReleased(e -> s.restart());
primaryStage.setScene(new Scene(new StackPane(textField), 350, 120));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
输出,只显示两个线程使用:
SCHEDULED
New task on thread Thread[Thread-5,5,main]
1
RUNNING
CANCELLED
READY
SCHEDULED
New task on thread Thread[Thread-6,5,main]
1
RUNNING
CANCELLED
READY
SCHEDULED
New task on thread Thread[Thread-6,5,main]
1
RUNNING
CANCELLED
READY
SCHEDULED
New task on thread Thread[Thread-6,5,main]
1
RUNNING
CANCELLED
READY
SCHEDULED
New task on thread Thread[Thread-6,5,main]
1
RUNNING
CANCELLED
READY
SCHEDULED
New task on thread Thread[Thread-6,5,main]
1
RUNNING
2
3
SUCCEEDED
我无法重现“巨大的延迟“与您发布的代码。你可以创建一个[MCVE]吗? –
@James_D也许你不能重现延迟,但你可以看到有很多线程被创建,我不希望这样的情况发生。 另外,我注意到在打印每个线程之前,生成的服务必须关闭,这需要一秒钟,对我来说太多了。 – user2468425
我不明白为什么创建新线程会导致问题,但是您是否阅读了[documentation](http://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Service.html #setExecutor-java.util.concurrent.Executor-)? “打印生成的服务产生的每个线程必须关闭之前”是什么意思?我不明白这一点。你至少能用代码来编辑你的问题,即使你不会发布代码来证明延迟? –