Java 如果其中一个线程抛出异常,如何停止所有正在运行的线程?
在我的一个应用程序中,我使用Java 如果其中一个线程抛出异常,如何停止所有正在运行的线程?,java,multithreading,Java,Multithreading,在我的一个应用程序中,我使用ExecutorService类创建一个固定线程池,并CountDownLatch等待线程完成。如果进程没有抛出任何异常,那么这可以正常工作。如果在任何线程中发生异常,我需要停止所有正在运行的线程,并向主线程报告错误。谁能帮我解决这个问题 这是我用于执行多个线程的示例代码 private void executeThreads() { int noOfThreads = 10; ExecutorService execu
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();
}
}
private void executeThreads()
{
int noOfThreads=10;
ExecutorService executor=Executors.newFixedThreadPool(noOfThreads);
尝试
{
CountDownLatch闩锁=新的CountDownLatch(noOfThreads);
for(inti=0;i
这是Executor类
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";
}
公共类ThreadExecutor实现可调用{
倒计时闩锁;
公共线程执行器(倒计时闩锁){
this.latch=闩锁;
}
@凌驾
公共字符串调用()引发异常
{
doMyTask();//进程逻辑在这里!
这个.latch.countDown();
返回“成功”;
}
=============================================================================
谢谢大家:)
我已经纠正了我的课,如下所示,这是现在的工作
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
}
}
}
private void executeThreads()
{
int noOfThreads=10;
ExecutorService executor=Executors.newFixedThreadPool(noOfThreads);
ArrayList futureList=新的ArrayList(noOfThreads);
尝试
{
userContext=BSF.getMyContext();
CountDownLatch latch=新的CountDownLatch(noOfComponentsToImport);
for(导入内容工件:工件列表){
添加(executor.submit(新线程执行器(闩锁));
}
satch.wait();
for(未来:未来列表)
{
尝试
{
future.get();
}
捕获(执行例外)
{//处理它
}
}
}
捕获(例外e){
//处理它
}
最后
{
executor.shutdown();
尝试
{
执行器等待终止(90000,时间单位毫秒);
}
捕捉(中断异常e)
{
//处理它
}
}
}
执行者类别:
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";
}
公共类ThreadExecutor实现可调用{
私有静态易失性布尔isAnyError;
倒计时闩锁;
公共线程执行器(倒计时闩锁){
this.latch=闩锁;
}
@凌驾
公共字符串调用()引发异常
{
试一试{
如果(!isAnyError)
{
doMyTask();//进程逻辑在这里!
}
}
捕获(例外e)
{
isAnyError=true;
投掷e;
}
最后
{
这个.latch.countDown();
}
返回“成功”;
}
我强烈建议您使用一个健壮的机制来倒计时闩锁。使用一个包罗万象的尝试最后{latch.countDown();}
使用一个单独的机制检测线程中的错误。我认为您还需要一个线程,称之为“观察者”,它将检查AtomicBoolean
的值是否为true
。设置后,您将关闭主执行服务。请记住,关闭机制不能保证立即停止所有线程。请阅读以下内容,例如:我认为您需要重新构造代码。查看
执行给定任务,返回已执行任务的结果
成功完成(即未引发异常),如果有
正常或异常返回时,未完成的任务
已取消。如果给定
此操作正在进行时,集合被修改
这似乎是您需要的行为。而且您不需要
倒计时闩锁
,因为main
将在invokeAny
中阻塞,请使用ExecutorCompletionService
,并在任务持续时间之外完成ExecutorService
(即,之后不会关闭):
由于任务1失败,任务2被取消。+1-是的,我总是从任何具有这种结构的线程代码开始,这样线程在没有通知“something”的情况下就无法逃逸。因此建议调用waittermination()作为一个解决方案?但是如何计算等待的时间?它似乎会返回第一个成功的。如果我想要所有成功的结果呢?谢谢。您需要添加executor.shutdownNow();executor.waitTermination(long.MAX_值,TimeUnit.NANOSECONDS);完全关闭它这个循环做什么?while(futuresIt.hasNext()){if(futuresIt.next().isDone()){futuresIt.remove();}else{complete=false;}}@devel这是在遍历集合时从集合中移除项的标准方法
completionService.take().get()
blocks,这是不好的。是的,你应该为你的所有web应用程序使用一个线程池。我认为上面的代码有问题。如果所有代码都没有异常执行,completionService.take()将等待服务器
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class Threader {
static ExecutorService service = Executors.newCachedThreadPool();
public static void main(String[] args) {
new Threader().start();
service.shutdown();
}
private void start() {
CompletionService<Void> completionService = new ExecutorCompletionService<Void>(
service);
/*
* Holds all the futures for the submitted tasks
*/
List<Future<Void>> results = new ArrayList<Future<Void>>();
for (int i = 0; i < 3; i++) {
final int callableNumber = i;
results.add(completionService.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
System.out.println("Task " + callableNumber
+ " in progress");
try {
Thread.sleep(callableNumber * 1000);
} catch (InterruptedException ex) {
System.out.println("Task " + callableNumber
+ " cancelled");
return null;
}
if (callableNumber == 1) {
throw new Exception("Wrong answer for task "
+ callableNumber);
}
System.out.println("Task " + callableNumber + " complete");
return null;
}
}
));
}
boolean complete = false;
while (!complete) {
complete = true;
Iterator<Future<Void>> futuresIt = results.iterator();
while (futuresIt.hasNext()) {
if (futuresIt.next().isDone()) {
futuresIt.remove();
} else {
complete = false;
}
}
if (!results.isEmpty()) {
try {
/*
* Examine results of next completed task
*/
completionService.take().get();
} catch (InterruptedException e) {
/*
* Give up - interrupted.
*/
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch (ExecutionException e) {
/*
* The task threw an exception
*/
System.out.println("Execution exception " + e.getMessage());
complete = true;
for (Future<Void> future : results) {
if (!future.isDone()) {
System.out.println("Cancelling " + future);
future.cancel(true);
}
}
}
}
}
}
}
Task 0 in progress
Task 2 in progress
Task 1 in progress
Task 0 complete
Execution exception java.lang.Exception: Wrong answer for task 1
Cancelling java.util.concurrent.FutureTask@a59698
Task 2 cancelled