Приложение JavaFX, которое использует Executor, зависает при выходе - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь создать клон Android AsyncTask для использования в приложении JavaFX. Вот код, который я придумал:

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

abstract public class AsyncTask<Param, Result>
{
    private Param param;
    private static Executor executor;

    public AsyncTask()
    {
        if (executor == null)
            executor = Executors.newSingleThreadExecutor();
    }

    protected void onPreExecute()
    {

    }

    protected Result doInBackground(Param param)
    {
        return null;
    }

    protected void onPostExecute(Result result)
    {

    }

    final public void execute(Param param)
    {
        this.param = param;

        onPreExecute();

        Task t = new Task();
        executor.execute(t);
    }

    private class Task implements Runnable
    {
        public void run()
        {
            Result result = doInBackground(param);
            onPostExecute(result);
        }
    }
}

Я могу использовать этот класс в своем приложении JavaFX, и он отлично работает, за исключением одной вещи: когда я закрываю главное окно, JVM зависает, а не завершает работу чисто. Я должен принудительно выйти из приложения.

Я думаю, что проблема связана с Исполнителем. Поскольку я не запускаю shutdown (), Executor зависает в ожидании выполнения большего количества задач. Поскольку AsyncTask является оболочкой для Executor Java, класс, расширяющий AsyncTask, не будет иметь прямого доступа к Executor и, следовательно, не сможет выполнить shutdown (). Как мне сделать упорядоченное выключение Исполнителя?

1 Ответ

0 голосов
/ 07 ноября 2018

Вам либо нужно выключить исполнителя из метода Application.stop, либо вы убедитесь, что поток Executor не будет препятствовать завершению работы JVM с помощью потока демона:

if (executor == null) {
    executor = Executors.newSingleThreadExecutor(r -> {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    });
}
...