在 Java 中使用执行器的串行调度队列?
Serial dispatch queue using Executors in Java?
我需要管理 Java 中的大量串行调度队列。有许多引擎模块需要每个模块管理自己的 运行 循环(其中一些可能很快完成,另一些可能会阻塞很长时间)。提交给每个引擎的作业必须运行顺序。
理想情况下,每个引擎都有一个在 0 到 1 个线程之间缩放的线程池,使 ExecutorService 既串行,又不会在有数百个线程的情况下占用大量资源,但只有少数人看到activity.
但是,当我尝试使用 或者:
new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue<>());
或
new ThreadPoolExecutor(1, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue<>());
我发现当提交第二份工作时(如果第一份工作仍然是 运行ning)抛出 RejectedExecutionException
,我假设因为我有一个线程到 运行两份工作,遗嘱执行人不喜欢这样。
我可以用我自己的队列和 start/stop/dispose 我自己的 Thread
按需实例来实现它,但这似乎是 0<=n<=1
执行器可以做的事情。
是否有 Executors.
方法(或 Executor 的实现)将创建一个缓存线程池,最多只有一个,如果没有作业,它也可以过期并死亡?
您的特定问题来自使用 SynchronousQueue,如文档所述:
A synchronous queue does not have any internal capacity, not even a capacity of one.
因此,如果您将其替换为 LinkedBlockingQueue,它确实有效。
但是,关于 Executors,您可以使用的是 Executors.newSingleThreadExecutor,因为它在顶部使用一个线程来执行任务。
一个简单的例子:
public static void main( String[] args )
{
ExecutorService executor = Executors.newFixedThreadPool(1);
TestThread t1 = new TestThread(1);
TestThread t2 = new TestThread(2);
executor.submit(t1);
Future<?> f2 = executor.submit(t2);
try {
f2.get();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ThreadPoolExecutor tt = (ThreadPoolExecutor) executor;
System.out.println(tt.getActiveCount()); //ensuring that there is no active threads in the pool after last thread terminates
}
public static class TestThread implements Runnable{
private int id;
public TestThread(int num){
id = num;
}
public void run() {
System.out.println("running thread: " + id);
try {
Thread.sleep(2000);
System.out.println("After sleeping thread " + id);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
给出预期的输出:
running thread: 1
After sleeping thread 1
running thread: 2
After sleeping thread 2
0
最后一个线程终止后没有活动线程。
我需要管理 Java 中的大量串行调度队列。有许多引擎模块需要每个模块管理自己的 运行 循环(其中一些可能很快完成,另一些可能会阻塞很长时间)。提交给每个引擎的作业必须运行顺序。
理想情况下,每个引擎都有一个在 0 到 1 个线程之间缩放的线程池,使 ExecutorService 既串行,又不会在有数百个线程的情况下占用大量资源,但只有少数人看到activity.
但是,当我尝试使用 或者:
new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue<>());
或
new ThreadPoolExecutor(1, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue<>());
我发现当提交第二份工作时(如果第一份工作仍然是 运行ning)抛出 RejectedExecutionException
,我假设因为我有一个线程到 运行两份工作,遗嘱执行人不喜欢这样。
我可以用我自己的队列和 start/stop/dispose 我自己的 Thread
按需实例来实现它,但这似乎是 0<=n<=1
执行器可以做的事情。
是否有 Executors.
方法(或 Executor 的实现)将创建一个缓存线程池,最多只有一个,如果没有作业,它也可以过期并死亡?
您的特定问题来自使用 SynchronousQueue,如文档所述:
A synchronous queue does not have any internal capacity, not even a capacity of one.
因此,如果您将其替换为 LinkedBlockingQueue,它确实有效。
但是,关于 Executors,您可以使用的是 Executors.newSingleThreadExecutor,因为它在顶部使用一个线程来执行任务。
一个简单的例子:
public static void main( String[] args )
{
ExecutorService executor = Executors.newFixedThreadPool(1);
TestThread t1 = new TestThread(1);
TestThread t2 = new TestThread(2);
executor.submit(t1);
Future<?> f2 = executor.submit(t2);
try {
f2.get();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ThreadPoolExecutor tt = (ThreadPoolExecutor) executor;
System.out.println(tt.getActiveCount()); //ensuring that there is no active threads in the pool after last thread terminates
}
public static class TestThread implements Runnable{
private int id;
public TestThread(int num){
id = num;
}
public void run() {
System.out.println("running thread: " + id);
try {
Thread.sleep(2000);
System.out.println("After sleeping thread " + id);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
给出预期的输出:
running thread: 1
After sleeping thread 1
running thread: 2
After sleeping thread 2
0
最后一个线程终止后没有活动线程。