import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* shutdown调用后,不可以再submit新的task,已经submit的将继续执行。
shutdownNow试图停止当前正执行的task,并返回尚未执行的task的list
* @author jeff
*
*/
public class ExecutorServiceTest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<String>> resultList = new ArrayList<Future<String>>();
// 创建10个任务并执行
for (int i = 0; i < 5; i++) {
/*
* 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
* 比如:本例中的5个task任务被submit进 队列中,并存入resultList集合中,这都是非阻塞的。
* for循环程序都会很快执行完毕。
*/
Future<String> future = executorService.submit(new TaskWithResult(i));
// 将任务执行结果存储到List中
resultList.add(future);
}
executorService.shutdown();
/**
* 遍历任务的结果:
* 任务被提交到队列后就会执行TaskWithResult的call()房,执行完毕后都会分别返回结果,注意只有在真正
* 在call返回数据结果后,下边的迭代中的fs.get(),才会返回打印结果。
* 而如果在执行call的过程中某一个task抛出ExecutionException异常,将被会被下边的迭代捕获到,
* 迭代逻辑中执行了executorService.shutdownNow()方法,导致其他所有的任务都退出不再执行!
*
*/
for (Future<String> fs : resultList) {
try {
System.out.println("======>"+fs.get()); // 打印各个线程(任务)执行的结果
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
executorService.shutdownNow();
e.printStackTrace();
return;
}
}
}
}
class TaskWithResult implements Callable<String> {
private int id;
public TaskWithResult(int id) {
this.id = id;
}
/**
* 任务的具体过程,一旦任务传给ExecutorService的submit方法,则该方法自动在一个线程上执行。
*
* @return
* @throws Exception
*/
public String call() throws Exception {
System.out.println("call()方法被自动调用,干活!!! " + Thread.currentThread().getName());
boolean b = new Random().nextBoolean();
System.out.println("boolean:"+b+" "+Thread.currentThread().getName());
if (b)
throw new TaskException("Meet error in task." + Thread.currentThread().getName());
// 一个模拟耗时的操作
for (int i = 9999999; i > 0; i--);
return Thread.currentThread().getName()+"的call()方法被自动调用,任务的结果是:" + id;
}
}
class TaskException extends Exception {
public TaskException(String message) {
super(message);
}
}
运行结果:
call()方法被自动调用,干活!!! pool-1-thread-3
boolean:false pool-1-thread-3
call()方法被自动调用,干活!!! pool-1-thread-4
boolean:true pool-1-thread-4
call()方法被自动调用,干活!!! pool-1-thread-1
boolean:false pool-1-thread-1
call()方法被自动调用,干活!!! pool-1-thread-2
boolean:true pool-1-thread-2
call()方法被自动调用,干活!!! pool-1-thread-5
boolean:false pool-1-thread-5
======>pool-1-thread-1的call()方法被自动调用,任务的结果是:0
java.util.concurrent.ExecutionException: executorTest.TaskException: Meet error in task.pool-1-thread-2
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
at java.util.concurrent.FutureTask.get(FutureTask.java:111)
at executorTest.ExecutorServiceTest.main(ExecutorServiceTest.java:34)
Caused by: executorTest.TaskException: Meet error in task.pool-1-thread-2
at executorTest.TaskWithResult.call(ExecutorServiceTest.java:64)
at executorTest.TaskWithResult.call(ExecutorServiceTest.java:1)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)