【问题标题】:Strange thread behavior when using ExecutorService使用 ExecutorService 时出现奇怪的线程行为
【发布时间】:2017-08-06 14:41:42
【问题描述】:

下面是我的代码:

public class Controller {
    public Button button_submitWork;

    @FXML
    public void handleSubmitWork(ActionEvent event) {
        final ExecutorService executorService = Executors.newFixedThreadPool(1, r -> {
            Thread t = Executors.defaultThreadFactory().newThread(r);
            t.setDaemon(true);
            return t;
        });//set thread daemon, let all threads terminate when the program is closed.
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("Executor Service thread");
                StringBuilder stringBuilder_output = new StringBuilder();
                for (int k = 0; k < 5; k++) {
                    stringBuilder_output.append(k);
                }
                //Thread.sleep(1000);
                return stringBuilder_output.toString() + "\n";
            }
        };
        Future<String> future = executorService.submit(callable);//Weird line. 
        //This line must be placed inside the "watchThread" to get the result, but why???
        Thread watchThread = new Thread(new Runnable() {
            @Override
            public void run() {
                //<----------Moving to here solve the problem!
                System.out.println("Watch thread");
                while (!Thread.currentThread().isInterrupted() && !future.isDone()) {
                    try {
                        String result = future.get();
                        System.out.println(result);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    } finally {
                        executorService.shutdownNow();
                    }
                }
            }
        });
        watchThread.setDaemon(true);
        watchThread.start();
        System.out.println("FX thread");
    }
}

问题是“watchThread”中的System.out.println(result); 从未被调用过。控制台输出如下所示:

Executor Service thread
FX thread
Watch thread

但是当我将Future&lt;String&gt; future = executorService.submit(callable); 移动到“watchThread”的运行方法内部时,输出变为:

FX thread
Watch thread
Executor Service thread
01234

这是我的预期。 我还发现如果call() 方法的任务更长,比如Thread.sleep(1000),输出会变成我预期的结果。

那是为什么呢?

【问题讨论】:

  • 除了下面的答案,你对这个循环有什么期望?当 Future.get 完成(正常或通过异常)时,您将在循环中准确获得退出条件之一。所以永远不会有第二轮。
  • 哦!是的你是对的。我应该删除 while 循环。在这种情况下,无需将内容放入 while 循环中。谢谢。

标签: java multithreading javafx


【解决方案1】:

您提交给executorService 的线程在此行之前完成:
while (!Thread.currentThread().isInterrupted() &amp;&amp; !future.isDone()) { 被调用,所以future.isDone 返回true 并且while 循环不会被执行。

如果添加Thread.sleep(1000),它仍然会运行,future.isDone 返回 false,while 循环会执行。当您将Future&lt;String&gt; future = executorService.submit(callable); 移动到watchThread 中时,也会发生同样的事情。

【讨论】:

  • 已解决,谢谢!而且我发现我应该删除while循环,它在这里没有用,甚至会导致问题。
猜你喜欢
  • 2013-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 2018-03-06
  • 1970-01-01
相关资源
最近更新 更多