Во-первых, я бы поставил под вопрос, зачем вам это нужно. Сама задача должна инкапсулировать всю логику, специфичную для своего конкретного экземпляра. Похоже, должно быть лучшее решение того, что вы пытаетесь достичь.
Таким образом, самый очевидный способ сделать это - вернуть Task
значение, которое вас интересует.
public class MyService extends Service<Integer> {
private int nextId = 0 ;
@Override
protected Task<Integer> createTask() {
private final int id = ++nextId ;
return new Task<Integer>() {
@Override
protected Integer call() throws Exception {
// do some work
return id;
}
};
}
}
Тогда
Service<Integer> service = new MyService();
service.setOnSucceeded(e -> System.out.println("Task " + service.getValue() + " finished"));
Заметим также, что вы можете переопределить succeeded()
метод Task
(а также регистрации обработчика с сервисом). Таким образом, вы можете сделать
public class MyService extends Service<Void> {
private int nextId = 0;
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
final int id = ++nextId ;
@Override
protected Void call() throws Exception {
// do some work
return null;
}
@Override
protected void succeeded() {
super.succeeded();
System.out.println("Task "+id+" completed successfully");
}
};
}
}
Метод succeeded()
вызывается на FX Application Thread.
Если вы действительно хотите управлять этим через службу, вы можете просто сохранить ссылку на последнюю задачу, которая была запущена в реализации службы. Поскольку Service
может запускать только одну задачу за раз, когда служба входит в состояние SUCCEEDED
, это гарантированно будет только что завершенной задачей. Например:
public class MyService extends Service<Void> {
private Task<Void> mostRecentTask ;
@Override
protected Task<Void> createTask() {
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
// do some work
return null;
}
};
task.setOnRunning(e -> mostRecentTask = task);
return task ;
}
public Task<Void> getMostRecentTask() {
return mostRecentTask ;
}
}
Тогда
MyService service = new MyService();
service.setOnSucceeded(e -> {
Task<Void> completedTask = service.getMostRecentTask();
// ...
});
Но, как я уже говорил, он чувствует, как должно быть более элегантный способ достичь то, что вы пытаетесь сделать на более фундаментальный уровень.
Я считаю, что каждый экземпляр службы может иметь не более 1 Task active в каждый момент времени. (Из документа [docs] (https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Service.html): * «Служба создает и управляет ** ** Задачей ... «*.) Эта задача может, разумеется, порождать дополнительные потоки, но затем сама отвечает за их синхронизацию. Вы также можете иметь несколько экземпляров одного класса службы, который, вероятно, вы хотите. Состояние каждого экземпляра службы привязано к состоянию соответствующей задачи, но, в отличие от задач, услуга может быть перезапущена (затем создается новая Задача). –
«Как можно запустить службу более одного раза одновременно». Это неверно. Данный экземпляр службы может выполнять только одну задачу за раз. –
IMHO, 'Service' может запускать несколько' Tasks', только обработчики событий 'Service' будут вызваны на основе состояния' Task'. – stepasite