Java 阻塞线程上是否有ExecutorService?
是否有Java 阻塞线程上是否有ExecutorService?,java,concurrency,executorservice,Java,Concurrency,Executorservice,是否有ExecutorService允许现有线程执行执行,而不是生成新线程?如果它是一个调度执行器,则会有额外的奖励。大多数执行器生成工作线程来执行,但我希望工作线程是我所在的现有线程。下面是我想象中的API: while (!executor.isTerminated()) { Runnable r = executor.take(); r.run(); } 这类似于SWT和JavaFX允许主线程分派事件的方式,而不是Swing,后者需要生成自己的事件分派线程来处理事件 动机
ExecutorService
允许现有线程执行执行,而不是生成新线程?如果它是一个调度执行器,则会有额外的奖励。大多数执行器生成工作线程来执行,但我希望工作线程是我所在的现有线程。下面是我想象中的API:
while (!executor.isTerminated()) {
Runnable r = executor.take();
r.run();
}
这类似于SWT和JavaFX允许主线程分派事件的方式,而不是Swing,后者需要生成自己的事件分派线程来处理事件
动机:我现在有很多地方,线程产生一个新的执行器,然后调用waittermination()等待它完成。我想节省一些资源,避免堆栈跟踪被一分为二
请注意,我不希望执行器在
execute(Runnable)
的调用线程中运行任务,这是和Guava所做的。我假设您想要的是控制新线程的创建,例如名称、守护进程状态等。使用线程工厂
:
public class MyThreadFactory implements ThreadFactory {
public Thread newThread(Runnable runnable) {
Thread t = new Thread(runnable, "MyThreadName");
t.setDaemon(true);
return t;
}
}
Executors.newExecutorOfSomeKind(new MyThreadFactory());
这允许您控制线程创建,以便在您制造的线程中执行,而不是在默认ThreadFactory
中的某个默认线程中执行
然后要使用它,Executors
中的所有方法都采用ThreadFactory
:
public class MyThreadFactory implements ThreadFactory {
public Thread newThread(Runnable runnable) {
Thread t = new Thread(runnable, "MyThreadName");
t.setDaemon(true);
return t;
}
}
Executors.newExecutorOfSomeKind(new MyThreadFactory());
编辑:我现在明白你的意思了。不幸的是,除了您提到的
sameThreadExecutor
之外,所有Executor
实现(据我所知)的行为都是创建新线程来运行任务。如果不通过线程
对象创建执行器只是为了执行一个任务(这是一个可怕的设计——请参阅注释了解我的意思),就没有简单的方法来完成您想要的任务。我建议将代码更改为使用单个Executor
,类似于ExecutorCompletionService
(请参阅)或使用fork/join模式。在Java7中,Fork/join变得更容易(请参阅)。对于Java 7之前的代码,请仔细阅读Java(和)中的计数。Java.util.concurrent中的大多数执行器的行为与您想象的完全相同。有些线程在任务太多时会产生额外的线程,但通常可以将它们配置为设置限制
要利用这种行为,不要每次启动新的执行器-使用相同的执行器。要等待一组任务完成,请使用或,然后您是否要求?或者可能?假设的
Executor#isTerminated()
谓词返回true后,它的答案如何变为false?@seh推测,isTerminated
读取一些volatile
变量,这些变量可以由另一个线程请求终止而更改。这毕竟是一个关于并发性的问题:3实现细节并没有解决我的设计问题。循环因依赖于先检查后行动协议而失效。在调用(SomeKindOf)Executor#take()
之前,(SomeKindOf)Executor#isTerminated()
表示的事实可能会发生变化。take()
是否返回null,或者抛出InterruptedException
?它需要一个比Runnable
更宽的codomain来指示它是在执行器终止后被调用的。@seh终止与关机不同。看看有两个值:shutdown(控制是否接受任务)和terminated(如果还有作业要执行,则返回true。因此,是的,一旦作业队列为空,关闭进程将中断其线程池中的所有线程,take
将抛出InterruptedException
。添加已注册的检查将允许线程正常终止,而不依赖异常。Obj对“恐怖设计”的质疑.java.util.concurrent中没有一个执行器实现为每个任务创建新线程。@Alexei Kaigorodov请参阅缓存线程池-。如果有许多长时间运行的任务,则每个任务都可能有自己的线程。@John Vint可能,但不是规则。如果可以,它将重用现有线程,即其线程的run()方法确实包含TS建议的循环任务队列。对,但说“java.util.concurrent中的任何执行器实现都不会为每个任务创建新线程”是有误导性的,我知道天真地使用的newCachedThreadPool
已经完全杀死了系统。@AlexeiKaigorodov@JohnVint,很明显,是“可怕的设计”,我的意思是让每个线程创建一个执行器来完成一组任务,但后来却销毁了该执行器,这是一个糟糕的设计。问题是:“我目前有很多地方,一个线程生成一个新的执行器,然后调用waitTermination()来等待它完成。”据我所知,他让他的线程1)创建一个执行器,2)提交作业,3)呼叫终止,4)呼叫等待终止。他没有使用类似于ExecutorCompletionService
或fork/join的东西,而是在每次线程运行时分配一个执行器。