1.线程池的5中创建方式:
- Single Thread Executor : 只有一个线程的线程池,因此所有提交的任务是顺序执行,代码: Executors.newSingleThreadExecutor()
- Cached Thread Pool : 线程池里有很多线程需要同时执行,老的可用线程将被新的任务触发重新执行,如果线程超过60秒内没执行,那么将被终止并从池中删除,代码:Executors.newCachedThreadPool()
- Fixed Thread Pool : 拥有固定线程数的线程池,如果没有任务执行,那么线程会一直等待,代码: Executors.newFixedThreadPool(4),在构造函数中的参数4是线程池的大小,你可以随意设置,也可以和cpu的数量保持一致,获取cpu的数量int cpuNums = Runtime.getRuntime().availableProcessors();
- Scheduled Thread Pool : 用来调度即将执行的任务的线程池,代码:Executors.newScheduledThreadPool()
- Single Thread Scheduled Pool : 只有一个线程,用来调度执行将来的任务,代码:Executors.newSingleThreadScheduledExecutor()
2.线程池的使用
方式一:提交 Runnable ,任务完成后 Future 对象返回 null
public class ThreadPoolWithRunable {
/**
* 通过线程池执行线程
* @param args
*/
public static void main(String[] args) {
//创建一个线程池
ExecutorService pool = Executors.newCachedThreadPool();
for(int i = 1; i < 5; i++){
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println("thread name: " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
pool.shutdown();
}
}
方式二:提交 Callable,该方法返回一个 Future 实例表示任务的状态
/**
* callable 跟runnable的区别:
* runnable的run方法不会有任何返回结果,所以主线程无法获得任务线程的返回值
*
* callable的call方法可以返回结果,但是主线程在获取时是被阻塞,需要等待任务线程返回才能拿到结果
* @author
*
*/
public class ThreadPoolWithcallable {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService pool = Executors.newFixedThreadPool(4);
for(int i = 0; i < 10; i++){
Future<String> submit = pool.submit(new Callable<String>(){
@Override
public String call() throws Exception {
//System.out.println("a");
Thread.sleep(5000);
return "b--"+Thread.currentThread().getName();
}
});
//从Future中get结果,这个方法是会被阻塞的,一直要等到线程任务返回结果
System.out.println(submit.get());
}
pool.shutdown();
}
}