线程池(重点)
池化技术
线程池 连接池 内存池 对象池... 程序运行的创建和销毁很耗费资源 池化技术就是事先准备好资源 需要时从池获取 用完放到池中 线程池好处 1.降低资源消耗 2.提高响应速度 3.方便管理
线程池3大方法
newSingleThreadExecutor newFixedThreadPool newCachedThreadPool
ExecutorService threadPool1 = Executors.newSingleThreadExecutor();//线程池只开一个线程 ExecutorService threadPool2 = Executors.newFixedThreadPool(5);//创建固定大小线程池 ExecutorService threadPool3 = Executors.newCachedThreadPool();//可伸缩的线程池 try { for (int i = 0; i < 10; i++) { threadPool1.execute(()->{//线程池中调用线程的方式 System.out.println(Thread.currentThread().getName()+"ok"); }); } }catch (Exception e){ e.printStackTrace(); }finally { threadPool1.shutdown();//线程池用完关闭 确保关闭放到finally中 }
点开3大方法的源码 都调用了ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) //corePoolSize 核心线程大小 //maximumPoolSize 最大线程大小 //keepAliveTime 超时释放大小 //unit 超时单位 //workQueue 阻塞队列 //threadFactory 线程工厂创建线程(若去重写方法这个不用动) //handler 拒绝策略 Executors的三大方法中newCachedThreadPool调用ThreadPoolExecutor的maximumPoolSize参数是值Integer.MAX_VALUE 21亿 可能导致内存溢出 建议直接用ThreadPoolExecutor而不是Executor
使用ThreadPoolExecutor自定义创建线程池
//在学习中 不知道ThreadPoolExecutor参数怎么定义 要点开源码 //如下参数的拒绝策略不知道怎么来定义的 就点开三大方法看它是怎么调用 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, 6, 3, TimeUnit.SECONDS, new LinkedBlockingDeque<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() ); 分析: 上例子核心线程2个 最大线程6个 队列3个 当大于2个线程启动 多的线程进队列等待(不会用到最大线程) 当大于5个线程如6个启动 核心线程用 了2个 队列等待3个 多的1个线程进入//即3个线程跑 3个线程等待 当大于9个线程启动 即线程池中最大6个线程都在跑 队列3个也满了 多出来的线程会执行拒绝策略 //4种拒绝策略(队列和最大线程都满了会执行策略) //AbortPolicy 抛异常(默认) //CallerRunsPolicy 哪条线程跑这个线程池就由哪条线程执行(一般主线程) //DiscardOldestPolicy 尝试丢掉旧线程 不会抛异常 //DiscardPolicy 不抛异常 线程丢失