Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 阻塞线程上是否有ExecutorService?_Java_Concurrency_Executorservice - Fatal编程技术网

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的东西,而是在每次线程运行时分配一个执行器。