我有一个ThreadPoolExecutor,其中一个线程将用于批处理,所以在将新任务分配给执行程序之前我必须等待先前的任务完成,我这样做取决于活动作业的值,但仔细观察我发现,执行者不会立即执行任务。
这对我造成的问题是我准备提供下一批但第一项任务尚未开始,因此活动作业的价值为0.
如何立即执行任务?我也可以使用任何其他执行者或方式来做到这一点。
答案 0 :(得分:1)
您应该使用submit
中的ExecutorService
方法安排任务。这是一个使用单线程执行程序来运行10个任务的工作程序。我转换为ThreadPoolExecutor
来监视线程池状态。您可以通过在相应的get
实例上调用Future
来等待单个任务,也可以通过调用awaitTermination
等待所有任务。如果您不需要Future
的结果,请使用Void
。希望它有所帮助。
public class Main {
static class TimingCallable implements Callable<Long> {
static int MIN_WAIT = 200;
@Override
public Long call() {
long start = System.currentTimeMillis();
try {
Thread.sleep(MIN_WAIT + new Random().nextInt(300));
} catch (InterruptedException e) {
//DO NOTHING
}
return System.currentTimeMillis() - start;
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(1);
@SuppressWarnings("unchecked")
Future<Long>[] futureResults = new Future[10];
for(int i =0; i < futureResults.length; i++) {
futureResults[i] = executor.submit(new TimingCallable());
System.out.println(String.format("ActiveCount after submitting %d tasks: ", i+1) + ((ThreadPoolExecutor)executor).getActiveCount());
System.out.println(String.format("Queue size after submitting %d tasks: ", i+1) + ((ThreadPoolExecutor)executor).getQueue().size());
}
Thread.sleep(2000);
System.out.println("ActiveCount after 2 seconds: " + ((ThreadPoolExecutor)executor).getActiveCount());
System.out.println("Queue size after 2 seconds: " + ((ThreadPoolExecutor)executor).getQueue().size());
for(int i =0; i < futureResults.length; i++) {
if (futureResults[i].isDone()) {
System.out.println(String.format("%d task is done with execution time: ", i) + futureResults[i].get());
}
} //Waiting for the last task to finish
System.out.println("Waiting for the last task result: " + futureResults[9].get());
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
}
}
答案 1 :(得分:0)
如果您只有一个线程要执行,只需使用LinkedQueue存储作业一旦线程完成执行,那么只会选择另一个任务。
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1,1, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>());
如果限制尺寸
,也可以有不同的策略http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
阅读已拒绝的任务
答案 2 :(得分:0)
显然,您希望立即按照提交的顺序运行多个任务。
非常简单:使用由单个线程支持的 executor service 。执行程序在等待较早的任务完成时会缓冲任务。在线程池中只有一个线程时,一次只能执行一个任务,因此将按照提交的顺序依次执行。
Executors
类提供了一些支持执行程序服务的不同线程池的选择。您需要Executors.newSingleThreadExecutor()
。
ExecutorService es = Executors.newSingleThreadExecutor() ;
提交一系列Runnable
或Callable
对象。每个代表要执行的任务。
es.submit( ( ) -> System.out.println( "Hello. " + Instant.now() ) ) ;
es.submit( ( ) -> System.out.println( "Bonjour. " + Instant.now() ) ) ;
es.submit( ( ) -> System.out.println( "Aloha. " + Instant.now() ) ) ;
es.submit( ( ) -> System.out.println( "Ciào. " + Instant.now() ) ) ;
es.submit( ( ) -> System.out.println( "Shwmai. " + Instant.now() ) ) ;
(可选)如果要跟踪任务的完成情况,则可以捕获每次调用submit
返回的Future
对象。 (上面的代码中未显示)
请参阅此code run live at IdeOne.com。
你好2019-11-29T09:10:13.426987Z
卓悦。 2019-11-29T09:10:13.472719Z
喂。 2019-11-29T09:10:13.473177Z
Ciào。 2019-11-29T09:10:13.473479Z
Shwmai。 2019-11-29T09:10:13.473974Z