В одном из моих приложений я использую класс ExecutorService
для создания фиксированного пула потоков и CountDownLatch
, чтобы дождаться завершения потоков. Это работает нормально, если этот процесс не вызвал каких-либо исключений. Если в любом из потоков возникло исключение, мне нужно остановить весь текущий поток и сообщить об ошибке в основной поток. Может ли кто-нибудь помочь мне решить эту проблему?
Это пример кода, который я использую для выполнения нескольких потоков.
private void executeThreads()
{
int noOfThreads = 10;
ExecutorService executor = Executors.newFixedThreadPool(noOfThreads);
try
{
CountDownLatch latch = new CountDownLatch(noOfThreads);
for(int i=0; i< noOfThreads; i++){
executor.submit(new ThreadExecutor(latch));
}
latch.await();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
executor.shutDown();
}
}
Это класс исполнителя
public class ThreadExecutor implements Callable<String> {
CountDownLatch latch ;
public ThreadExecutor(CountDownLatch latch){
this.latch = latch;
}
@Override
public String call() throws Exception
{
doMyTask(); // process logic goes here!
this.latch.countDown();
return "Success";
}
=============================================== ==============================
Спасибо всем:)
Я скорректировал свой класс, как показано ниже, и теперь он работает.
private void executeThreads()
{
int noOfThreads = 10;
ExecutorService executor = Executors.newFixedThreadPool(noOfThreads);
ArrayList<Future<Object>> futureList = new ArrayList<Future<Object>>(noOfThreads );
try
{
userContext = BSF.getMyContext();
CountDownLatch latch = new CountDownLatch(noOfComponentsToImport);
for(ImportContent artifact:artifactList){
futureList.add(executor.submit(new ThreadExecutor(latch)));
}
latch.await();
for(Future<Object> future : futureList)
{
try
{
future.get();
}
catch(ExecutionException e)
{ //handle it
}
}
}
catch (Exception e) {
//handle it
}
finally
{
executor.shutdown();
try
{
executor.awaitTermination(90000, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e)
{
//handle it
}
}
}
Класс исполнителя:
public class ThreadExecutor implements Callable<String> {
private static volatile boolean isAnyError;
CountDownLatch latch ;
public ThreadExecutor(CountDownLatch latch){
this.latch = latch;
}
@Override
public String call() throws Exception
{
try{
if(!isAnyError)
{
doMyTask(); // process logic goes here!
}
}
catch(Exception e)
{
isAnyError = true ;
throw e;
}
finally
{
this.latch.countDown();
}
return "Success";
}