首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“主”线程的Java执行器

“主”线程的Java执行器
EN

Stack Overflow用户
提问于 2019-08-05 21:36:54
回答 4查看 3.9K关注 0票数 1

我想从程序的“主”线程创建一个Executor (类似于Android中的主活套 ),然后运行直到它处理了提交给它的所有内容:

代码语言:javascript
复制
public class MyApp {
  private static Callable<Integer> task = () -> {
    // ... return an int somehow ...
  };

  public static void main(String[] args) throws ExecutionException, InterruptedException {
    ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
    Thread main = Thread.currentThread();
    ExecutorService executorService = Executors.newSingleThreadExecutor(r -> main);

    service.submit(task).addListener(() -> {
      /// ... do something with the result ...
    }, executorService);

    executorService.awaitTermination(100, TimeUnit.SECONDS);
  }
}

但我得到了一个IllegalThreadState异常:

代码语言:javascript
复制
SEVERE: RuntimeException while executing runnable MyApp$$Lambda$20/0x00000008000a6440@71f06a3c with executor java.util.concurrent.Executors$FinalizableDelegatedExecutorService@47add263
java.lang.IllegalThreadStateException
    at java.base/java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:926)
    at java.base/java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1343)
    at java.base/java.util.concurrent.Executors$DelegatedExecutorService.execute(Executors.java:687)
    at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1137)
    at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:957)
    at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:726)
    at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.afterRanInterruptibly(TrustedListenableFutureTask.java:131)
    at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:133)
    at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:78)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

我可以在一个新线程上启动一个ExecutorService,然后等待它,但这似乎是浪费。

是否有一种从当前线程创建Executor 的好方法,并等待它处理提交给它的所有东西?

EN

回答 4

Stack Overflow用户

发布于 2019-08-06 07:34:46

使用番石榴的MoreExecutors.newDirectExecutorService()

这将确保提交的代码将在ThreadPool的同一个线程中执行。我知道,它不是主线程,但至少您不像您想要的那样为侦听器创建其他新线程。

代码语言:javascript
复制
import com.google.common.util.concurrent.*;
import org.junit.jupiter.api.Test;
import java.util.concurrent.*;

class ExecutorTest {
  private static Callable<Integer> task = () -> {
    System.out.println("in call: " + Thread.currentThread().getName());
    TimeUnit.SECONDS.sleep(1);
    return 0;
  };
  @Test
  void test() throws InterruptedException {
    ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
    ExecutorService executor = MoreExecutors.newDirectExecutorService();
    service.submit(task).addListener(() -> {
      System.out.println("in listener: " + Thread.currentThread().getName());
    }, executor);
    executor.awaitTermination(2, TimeUnit.SECONDS);
  }
}
票数 2
EN

Stack Overflow用户

发布于 2019-08-05 21:43:53

invokeAll()文档化的这里方法等待所有任务的完成

你能做到的

代码语言:javascript
复制
executorService.invokeAll();

请跟随这个职位获得更多解释

票数 0
EN

Stack Overflow用户

发布于 2019-08-05 23:05:08

您正在尝试在主线程中执行回调。简单的方法是调用get()

代码语言:javascript
复制
YourResult result = service.submit(task).get();
/* Do something with your result... */

如果您想异步执行回调,您可能对CompletionStage感兴趣。

代码语言:javascript
复制
CompletableFuture.runAsync(task).thenAccept(r -> /* do something with result */);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57366374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档