我正在以下列方式使用Java执行器,但不确定每行是否必要,以及这是否正确使用它:
ExecutorService executor=Executors.newFixedThreadPool(30);
...
int N=200;
CountDownLatch doneSignal=new CountDownLatch(N);
for (int i=0;i<N;i++) executor.execute(new Test_Runner(doneSignal,...));
doneSignal.await();
executor.shutdown();
while (!executor.isTerminated()) { Thread.sleep(1000); }
// Blocks until all tasks have completed execution after a shutdown request
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
...
class Test_Runner implements Runnable
{
private CountDownLatch doneSignal;
Thread Test_Runner_Thread;
public Tes_Runner(CountDownLatch doneSignal,...)
{
this.doneSignal=doneSignal;
}
// Define some methods
public void run()
{
try
{
// do some work
}
catch (Exception e)
{
e.printStackTrace();
}
doneSignal.countDown();
}
public void start()
{
if (Test_Runner_Thread==null)
{
Test_Runner_Thread=new Thread(this);
Test_Runner_Thread.setPriority(Thread.NORM_PRIORITY);
Test_Runner_Thread.start();
}
}
public void stop() { if (Test_Runner_Thread!=null) Test_Runner_Thread=null; }
}
答案 0 :(得分:1)
对我来说是正确的。在过去,我遵循了Java 7 JavaDoc for ExecutorService的建议实现来停止它。您可以从Java 7 Javadoc获得它,但为方便起见,我在下面提供它。编辑它以满足您的需求,例如您可能希望传递等待的秒数。使用CountDownLatch的好处是,等待它时,您知道ExecutorService将立即终止。此外,您可能希望在未来的真实案例中为您的锁存器添加超时等待时间。另外,在现实世界的应用程序中使用时,将latch.countDOwn()置于try终端块中。
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
答案 1 :(得分:1)
您可以进一步简化代码。
CountDownLatch
。 Callable
任务。创建Callable
任务的ArrayList。
List<Test_Runner> callables = new ArrayList<Test_Runner>();
for (int i=0;i<N;i++) {
callables.add(new Test_Runner());
}
在executorService上使用invokeAll()
。
List<Future<String>> futures = executorService.invokeAll(callables);
来自javadocs,
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException
执行给定的任务,在完成所有任务后返回持有其状态和结果的Futures列表。对于返回列表的每个元素,Future.isDone()都为true。请注意,已完成的任务可能正常终止或通过抛出异常终止。如果在此操作正在进行时修改了给定集合,则此方法的结果未定义。
您可以按照Jose Martinez的建议关闭executorService