线程池基础
一、线程池基础
线程池:3大方法、7大参数、4种拒绝策略
1. 为什么会出现池化技术
Java中的池大概有:线程池,连接池,内存池,对象池等。
创建、销毁这种动作十分浪费资源,因此可以事先准备好一部分资源,谁要用就来直接取,取完了还回来,这就是池化技术。
线程池的优点:
- 
降低资源的消耗 
- 
提高响应的速度 
- 
方便管理。 
2.线程池的三大方法(不推荐)
//单个线程
ExecutorService service = Executors.newSingleThreadExecutor();
//固定大小线程池
ExecutorService service = Executors.newFixedThreadPool(5);
//可伸缩
ExecutorService service = Executors.newCachedThreadPool();
3.七大参数
先来看看三大方法的源码
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}
可以看到他们最终都是采用ThreadPoolExecutor 创建的线程池
public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小 
                              int maximumPoolSize, // 最大核心线程池大小 
                              long keepAliveTime, // 超时了没有人调用就会释放 
                              TimeUnit unit, // 超时单位 
                              BlockingQueue<Runnable> workQueue, // 阻塞队列 
                              ThreadFactory threadFactory, // 线程工厂:创建线程的,一般 不用动 
                              RejectedExecutionHandler handle // 拒绝策略
                         ) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
在阿里Java开发手册中这样写道

4.四种拒绝策略
new ThreadPoolExecutor.AbortPolicy() 	     // 银行满了,还有人进来,不处理这个人的,抛出异 常
new ThreadPoolExecutor.CallerRunsPolicy()    // 哪来的去哪里!
new ThreadPoolExecutor.DiscardPolicy()       //队列满了,丢掉任务,不会抛出异常!
new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试去和最早的竞争,也不会 抛出异常!
5.代码实例
package com.shimeath.demo11;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
 * @author Shimeath
 */
public class TestThreadPoolExecutors {
    public static void main(String[] args) {
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
                2,
                5,
                0,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        try {
            for (int i = 0; i < 9; i++) {
                poolExecutor.execute(()->{
                    System.out.println(Thread.currentThread().getName() + " ok");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            poolExecutor.shutdown();
        }
    }
}
6.扩展
池的最大的大小如何去设置!
了解:IO密集型,CPU密集型:(调优)
// 最大线程(maximumPoolSize)到底该如何定义 
// 1、CPU 密集型,几核,就是几,可以保持CPu的效率最高! 
// 2、IO 密集型 > 判断你程序中十分耗IO的线程, 
// 程序 15个大型任务 io十分占用资源! 可以采用30个   
// 获取CPU的核数 
System.out.println(Runtime.getRuntime().availableProcessors());

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号