ExecutorService的invokeAny方法

一、此方法获得最先完成任务的结果,即Callable<T>接口中的call的返回值,在获得结果时,会中断其他正在执行的任务

示例代码:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class MyinvokeAny {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		List<Callable<String>> list=new ArrayList<Callable<String>>();
		list.add(new MyCallable_iAny1());
		list.add(new MyCallable_iAny2());
		ExecutorService executor=Executors.newCachedThreadPool();
		
		try {
			String str=executor.invokeAny(list);//取出第一个执行完的任务时,其他未完成的任务会被中断
			System.out.println(str);
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		
		
	}

}
class MyCallable_iAny1 implements Callable<String>{

	@Override
	public String call() throws Exception {
		// TODO 自动生成的方法存根
		try{
			for(int i=0;i<123456;i++){
				for(int j=0;j<123;j++){
					if(Thread.currentThread().isInterrupted()){
						System.out.println("this is a exception");
						throw new InterruptedException("A InterruptedException");
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}
		
		System.out.println("finish");
		return "call_1";
	}
	
}
class MyCallable_iAny2 implements Callable<String>{

	@Override
	public String call() throws Exception {
		// TODO 自动生成的方法存根
		Thread.sleep(1000);
		return "call_2";
	}
	
}

  运行结果:

call_2java.lang.InterruptedException: A InterruptedException

this is a exception
	at myexecutorservice.MyCallable_iAny1.call(myinvokeAny.java:53)
	at myexecutorservice.MyCallable_iAny1.call(myinvokeAny.java:1)
	at java.util.concurrent.FutureTask.run(Unknown Source)

  

二、异常的处理

对于会先完成,但会出现异常的任务,ExecutorService会将关注点换到下一个任务,若果所有的任务都出现异常,那么将会只获得最后一个任务的异常(例如,有3个任务A,B,C,这三个任务都会出现异常,但是只会获得C任务的异常)

示例代码:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class myinvokeAny {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		List<Callable<String>> list=new ArrayList<Callable<String>>();
		list.add(new MyCallable_iAny1());
		list.add(new MyCallable_iAny2());
		ExecutorService executor=Executors.newCachedThreadPool();
		
		try {
			String str=executor.invokeAny(list);//取出第一个执行完的任务时,其他未完成的任务会被中断

			System.out.println(str);
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		
		
	}

}
class MyCallable_iAny1 implements Callable<String>{

	@Override
	public String call() throws Exception {
		// TODO 自动生成的方法存根
		Thread.sleep(2000);
		
		System.out.println("finish");
		return "call_1";
	}
	
}
class MyCallable_iAny2 implements Callable<String>{

	@Override
	public String call() throws Exception {
		// TODO 自动生成的方法存根
		Thread.sleep(1000);
		if(true){
			throw new Exception("myException_B");
		}
		return "call_2";
	}
	
}

  运行结果:

finish
call_1

  由此,我们可以看出,MyCallable_iAny2任务出现异常,从而将任务的关注点移到了MyCallable_iAny1任务,并不会打印出异常信息。如果,想打印出异常信息,需要这样写:

写法一:

                try{
			if(true){
				throw new Exception("myException_B");
			}
		}catch(Exception e){
			e.printStackTrace();
}

运行结果:

java.lang.Exception: myException_B
call_2
	at myexecutorservice.MyCallable_iAny2.call(myinvokeAny.java:76)
	at myexecutorservice.MyCallable_iAny2.call(myinvokeAny.java:1)

这里获得了异常任务的结果,这是因为MyCallable_iAny2的异常状态未上报,这导致线程池认为其是正确的,从而未将关注点换到下一个任务

写法二:

try{
			if(true){
				throw new Exception("myException_B");
			}
		}catch(Exception e){
//			e.printStackTrace();
			throw e;
		}

运行结果:

finish
call_1

  这里抛出了异常,从了线程池将关注点换到了下一个任务

原文地址:https://www.cnblogs.com/l1019/p/6755992.html