1、execute和submit提交的区别
1 execute只能提交Runnable类型的任务,无返回值。submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任务类型为Runnable时,返回值为null。
2 execute在执行任务时,如果遇到异常会直接抛出,而submit不会直接抛出,只有在使用Future的get方法获取返回值时,才会抛出异常。
2、线程池的7个参数含义
corePoolSize:核心线程池的大小。当提交一个任务到线程池时,核心线程池会创建一个核心线程来执行任务,即使其他核心线程能够执行新任务也会创建线程,等到需要执行的任务数大于核心线程池基本大小时就不再创建。如果调用了线程池的 prestartAllCoreThreads() 方法,核心线程池会提前创建并启动所有核心线程。
maximumPoolSize:线程池允许创建的最大线程数。如果队列也满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的空闲线程执行任务。值得注意的是,如果使用了无界的任务队列则这个参数不起作用。
keepAliveTime:当线程池中的线程数大于 corePoolSize 时,keepAliveTime 为多余的空闲线程等待新任务的最长时间,超过这个时间后多余的线程将被终止。所以,如果任务很多,并且每个任务执行的时间比较短,可以调大时间,提高线程的利用率。值得注意的是,如果使用了无界的任务队列则这个参数不起作用。
TimeUnit:线程活动保持时间的单位。
workQueue:任务队列。当核心线程池中没有线程时,所提交的任务会被暂存在队列中。Java 提供了多种阻塞队列。
threadFactory:创建线程的工厂。可以通过线程工厂给每个创建出来的线程设置符合业务的名字。
handler:
ThreadPoolExecutor默认有四个拒绝策略:
1、ThreadPoolExecutor.AbortPolicy()
直接抛出异常RejectedExecutionException
2、ThreadPoolExecutor.CallerRunsPolicy()
直接调用run方法并且阻塞执行
3、ThreadPoolExecutor.DiscardPolicy()
直接丢弃后来的任务
4、ThreadPoolExecutor.DiscardOldestPolicy()
丢弃在队列中队首的任务
3 execute使用Runnable参数,submit如果需要返回值,优先使用Callable
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadFactory nameFactory = new ThreadFactoryBuilder().setNameFormat("send-pool-%d").build();
ExecutorService executor = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(100), nameFactory,
new ThreadPoolExecutor.AbortPolicy());
final int a = 666;
for(int i = 0; i < 50; i++){
Future<Integer> submit = executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(100);
return a;
}
});
System.out.println(submit.get());
}
/*
for(int i = 0; i < 50; i++){
executor.execute(new Runnable(){
public void run(){
try{
System.out.println(Thread.currentThread().getName());
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
*/
System.out.println(1111111111);
executor.shutdown();
}