线程池的底层用的是ThreadPoolExecutor
线程池不需要new,已经写好池化
注意:使用池化线程,永远使用关闭,关闭比使用更重要
实例一:创建固定大小的线程池
/**
* 创建固定大小的线程池
*/
private static void ExecutorNewFixedThreadPool() {
ExecutorService executorService = newFixedThreadPool(5);
try{
//模拟10个用户来办理用户,一个用户相当于外来的请求线程
for(int i = 0 ; i < 10 ;i++){
executorService.execute(() ->{
System.out.println("当前线程为"+Thread.currentThread().getName());
});
}
}catch (Exception e){
e.printStackTrace();
}finally {
executorService.shutdown();
}
}
实例二:创建只有一个处理线程的线程池
/**
* 创建只有一个处理线程的线程池
*/
private static void ExecutorsNewSingleThreadExecutor() {
//创建只有一个处理线程的线程池
ExecutorService executorService = newSingleThreadExecutor();
try{
//模拟5个用户处理业务,一个用户相当于外来的请求线程
for(int i = 0 ; i < 5 ; i++){
executorService.execute(()->{
System.out.println("当前处理线程为:"+Thread.currentThread().getName());
});
}
}catch (Exception e){
e.printStackTrace();
}finally {
//关闭线程池
executorService.shutdown();
}
}
实例三:创建一池多线程,如果当前线程能出来相应的业务不会创建新的线程,如果出来不过来会创建新的线程
/**
* 创建一池多线程
*/
private static void ExecutorsNewCachedThreadPool() {
//创建一池多线程
ExecutorService executorService = newCachedThreadPool();
try{
//模拟15个用户来办理业务,每个用户相当于一个外来的请求线程
for (int i = 0 ; i < 15 ; i++){
executorService.execute(()->{
System.out.println("当前线程为:"+Thread.currentThread().getName());
});
}
}catch (Exception e){
e.printStackTrace();
}finally {
//关闭线程池
executorService.shutdown();
}
}
显示效果
当前线程为:pool-1-thread-3
当前线程为:pool-1-thread-6
当前线程为:pool-1-thread-5
当前线程为:pool-1-thread-4
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-2
当前线程为:pool-1-thread-8
当前线程为:pool-1-thread-7
当前线程为:pool-1-thread-9
当前线程为:pool-1-thread-10
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-9
当前线程为:pool-1-thread-7
当前线程为:pool-1-thread-10
当前线程为:pool-1-thread-8
如果中间停隔1秒实例
/**
* 创建一池多线程 如果当前线程能出来相应的业务不会创建新的线程,如果出来不过来会创建新的线程
*/
private static void ExecutorsNewCachedThreadPool() {
//创建一池多线程
ExecutorService executorService = newCachedThreadPool();
try{
//模拟15个用户来办理业务,每个用户相当于一个外来的请求线程
for (int i = 0 ; i < 15 ; i++){
executorService.execute(()->{
System.out.println("当前线程为:"+Thread.currentThread().getName());
});
//如果中间停顿1秒,可能只有1个线程进行处理
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
}
}catch (Exception e){
e.printStackTrace();
}finally {
//关闭线程池
executorService.shutdown();
}
}
显示结果
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
当前线程为:pool-1-thread-1
Executors.newFixThreadPool底层
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
Executors.newSingleThreadExecutor底层
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
Executors.newCachedThreadPool底层
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
共同点:都是用了ThreadPoolExecutor对象,传入五大参数(包含阻塞队列)