Может ли служба запускать несколько задач?

#javafx #multitasking

#javafx #многозадачность

Вопрос:

Мне нужно использовать a Service , который запускает a Task более одного раза (= одно и то же Service должно выполняться несколько раз параллельно Task ). Я прочитал документацию JavaFX, и, похоже, они говорят, что a Service может запускать только одну Task задачу одновременно.

Поэтому, если я дважды вызову start свой Service объект, первый Task , возвращенный его createTask методом, будет остановлен, как если бы я использовал restart после первого start .

Однако это неясно. Как я уже говорил, документация, похоже, говорит об этом. Действительно :

Служба создает и управляет задачей, которая выполняет работу в фоновом потоке.

Обратите внимание, что я мог бы подумать, что они также говорят, что a Service может Task запускать несколько задач одновременно. Действительно :

Служба может быть создана декларативно и перезапущена по требованию.

Мой вопрос: если я использую N start подряд, будет Tasks ли создано N И БУДЕТ ЛИ ВЫПОЛНЯТЬСЯ КАЖДОЕ ИЗ НИХ?

Ответ №1:

«Если я использую N запусков подряд, будут ли созданы N задач И БУДУТ ЛИ ВЫПОЛНЯТЬСЯ КАЖДАЯ ИЗ НИХ?

Короче говоря, нет.

«Если я start дважды вызову свой Service объект …»

Из Javadocs:

public void start()

Запускает эту службу. Для успешного выполнения этого вызова служба должна быть в состоянии ГОТОВНОСТИ.

Поэтому, если вы вызовете start() второй раз без предварительного вызова reset() , вы просто получите исключение. Вы можете вызывать только reset() в том случае, если Service он не находится в RUNNING SCHEDULED состоянии или. Вы можете вызвать restart() , что приведет сначала к отмене любой текущей задачи, а затем к перезапуску службы. (Это то, что подразумевается в документации, в которой говорится, что «служба может быть перезапущена по требованию».)

Конечным результатом этого является то, что служба не может одновременно выполнять две текущие задачи, поскольку не существует последовательности вызовов, которые могут привести к этой ситуации без вызова IllegalStateException .

Если вы хотите, чтобы одновременно выполнялось несколько задач, просто создайте их самостоятельно и отправьте исполнителю (или запустите каждую в своем собственном потоке, но предпочтительнее исполнитель):

 private final Executor exec = Executors.newCachedThreadPool(runnable -> {
    Thread t = new Thread(runnable);
    t.setDaemon(true);
    return t ;
});

// ...

private void launchTask() {

    Task<MyDataType> task = new Task<MyDataType>(){
        @Override
        protected Something call() {
            // do work...
            return new MyDataType(...);
        }
    };
    task.setOnSucceeded(e -> { /* update UI ... */ });
    task.setOnFailed(e -> { /* handle error ... */ });
    exec.execute(task);

}
  

Комментарии:

1. Чем ты! Вы знаете, могу ли я заставить поток приложения JavaFX ждать состояния службы «УСПЕШНО»? Это позволит мне запускать несколько задач с единственным потоком, когда будет достигнуто это состояние (я знаю: параллелизма не будет … кроме как между последней задачей и потоком приложения JavaFX).

2. Хорошо; документ JFX указывает, что исполнитель может быть добавлен в службу. Как вы думаете, я могу объединить свою службу ее задачу исполнителя, который будет использовать последнюю? (Я бы хотел сохранить свою службу на самом деле)

3. Я совершенно не понимаю, чего вы пытаетесь достичь на данный момент. Если вы хотите, чтобы задачи выполнялись параллельно, вы не можете управлять ими с помощью a Service (с или без an Executor , что является просто деталью реализации службы). Если вы не хотите, чтобы они выполнялись параллельно, почему бы просто не превратить их в одну выполняемую (или одну задачу)? Если вы хотите, чтобы они выполнялись параллельно, и хотите знать, когда все они будут завершены, используйте a CountDownLatch в отдельном потоке.

4. На самом деле, что я действительно хочу сделать, так это запустить несколько задач одновременно. Я неправильно выразился. Ну, у меня просто есть поток приложения JavaFX, который запускает N с Task помощью a, Service и я хотел бы запустить их все параллельно. Вы сказали мне использовать an Executor (a CountDownLatch было бы неверно, потому что, как вы мне сказали, поток JFXAPP не может ждать). Таким образом, я собираюсь использовать Executor . В коде, который вы опубликовали вместе с the Executor , я не нашел связи между the Task и the Executor ?

5. «Я не нашел связи между Task и Executor » . Последняя строка кода: exec.execute(task)