java - “主”线程的 Java 执行器
问题描述
我想Executor
从程序的“主”线程(类似于 Android 中的主循环器)创建一个,然后运行直到它处理完提交给它的所有内容:
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
例外:
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
从当前线程创建一个并等待它处理已提交给它的所有内容的好方法?
解决方案
使用番石榴MoreExecutors.newDirectExecutorService()
这将确保提交的代码将在 ThreadPool 的同一线程中执行。我知道,它不是主线程,但至少您不会像您想要的那样仅为侦听器创建其他新线程。
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);
}
}
推荐阅读
- javascript - rails 在本地工作,但在 heroku 上服务器 statut 304
- reactjs - 如何为使用的数组设置初始/默认值
? - python - 无法在 DJANGO 中完成基于 Unittest 类的视图
- c# - CreateWebHostBuilder 的 C# Lambda 表达式
- ajax - 第二次触发 JQuery Ajax 时,数据未绑定到 vuejs2,尽管 Vue 对象中的数据更新
- adb - 是否可以将应用程序中的复制/粘贴/输入(例如密码)复制到 Oculus Quest 头戴设备中?
- javascript - 未处理的拒绝(错误):预期未定义为 GraphQL 模式
- javascript - 在另一个文件中触发 https 请求时如何将对象返回给客户端?
- python - 如何解决,PermissionError: [Errno 13] Permission denied: 'test.from'
- android - 如果用户已经登录,则跳过登录屏幕