1. 拒绝策略
- AbortPolicy: 当提交的任务超过了线程池的任务队列大小;则会直接抛出异常,拒绝接收此任务;其它的任务依然执行。
- DiscardPolicy:当提交的任务超过了线程池的任务队列大小;不会产生任何现象,线程池会直接丢弃此任务;不建议使用。
- CallerRunPolicy:不会提交给线程池执行任务,而是,直接使用当前提交任务的线程去执行此任务,会阻塞提交任务的线程的执行。。
public class ExecutorServiceReject {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = new ThreadPoolExecutor(1, 2,
60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), (r)-> {
Thread thread = new Thread(r);
return thread;
}, new ThreadPoolExecutor.CallerRunsPolicy());
IntStream.rangeClosed(0, 2).boxed().forEach(i -> {
executorService.execute(() -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
});
TimeUnit.SECONDS.sleep(3);
executorService.execute(() -> {
System.out.println("XXXXXXXXX");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
});
System.out.println("main函数执行完毕!");
}
}
- DiscardOldestPolicy:会把最初放入任务队列中的任务(未被执行的)丢弃。
2. ExecutorService API
getActiveCount()
:获取当前线程池中活跃的线程个数;若是没有execute(Runnable)
任务的话,是不会创建线程的;提交一个任务,也只会创建一个线程去执行,而不会一次性直接创建corePoolSize
个线程。allowCoreThreadTimeOut(true)
:当任务执行完成的时候,释放线程池;若使用的线程池的keepAliveTime为0,需要手动修改,因为不允许keepAliveTime为0的线程池,调用此方法;invokeAny(Call<T>)
:此方法是一个同步方法,会阻塞调用线程;若其中有一个任务返回了,则其它的任务取消,不会继续执行; 此方法也存在超时设置重构方法;防止线程一直等待;无法结束。
private static void testInvokeAny() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<Callable<Integer>> callableList = IntStream.rangeClosed(1, 5).boxed().map(
i -> (Callable<Integer>) () -> {
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(10));
System.out.println(Thread.currentThread().getName() + " --> " + i);
return i;
}).collect(Collectors.toList());
Integer resultValue = executorService.invokeAny(callableList);
System.out.println("result: " + resultValue);
}
invokeAll()
:此方法是一个同步方法,会阻塞调用线程;此方法也存在超时设置重构方法;防止线程一直等待;无法结束。
private static void testInvokeAll() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<Callable<Integer>> callableList = IntStream.rangeClosed(1, 5).boxed().map(
i -> (Callable<Integer>) () -> {
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(10));
System.out.println(Thread.currentThread().getName() + " --> " + i);
return i;
}).collect(Collectors.toList());
List<Future<Integer>> resultValue = executorService.invokeAll(callableList);
resultValue.stream().forEach(item -> {
try {
System.out.println(item.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}