1.创建普通对象,只是在JVM的堆里分配一块内存而已
2.创建线程,需要调用操作系统内核的API,然后操作系统需要为线程分配一系列资源,成本很高
// 假设Java线程池采用一般意义上池化资源的设计方法 class ThreadPool { // 获取空闲线程 Thread acquire() { } // 释放线程 void release(Thread t) { } } // 期望的使用 ThreadPool pool; Thread T1 = pool.acquire(); // 传入Runnable对象 T1.execute(() -> { // 具体业务逻辑 });
业界线程池的设计,普遍采用生产者-消费者模式,线程池的使用方是生产者,线程池本身是消费者
public class MyThreadPool { // 工作线程负责消费任务并执行任务 class WorkerThread extends Thread { @Override public void run() { // 循环取任务并执行 while (true) { Runnable task = null; try { task = workQueue.take(); } catch (InterruptedException e) { } task.run(); } } } // 利用阻塞队列实现生产者-消费者模式 private BlockingQueue<Runnable> workQueue; // 内部保存工作线程 List<WorkerThread> threads = new ArrayList<>(); public MyThreadPool(int poolSize, BlockingQueue<Runnable> workQueue) { this.workQueue = workQueue; for (int i = 0; i < poolSize; i++) { WorkerThread work = new WorkerThread(); work.start(); threads.add(work); } } // 提交任务 public void execute(Runnable command) throws InterruptedException { workQueue.put(command); } public static void main(String[] args) throws InterruptedException { // 创建有界阻塞队列 BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(2); // 创建线程池 MyThreadPool pool = new MyThreadPool(10, workQueue); // 提交任务 pool.execute(() -> { System.out.println("hello"); }); } }
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) // 让所有线程都支持超时,如果线程池很闲,那么将撤销所有线程 public void allowCoreThreadTimeOut(boolean value)
1.corePoolSize:线程池保有的最小线程数
2.maximumPoolSize:线程池创建的最大线程数
3.keepAliveTime & unit
4.workQueue:工作队列
5.threadFactory:自定义如何创建线程
6.handler
1.不建议使用Executors,因为Executors提供的很多默认方法使用的是无界队列LinkedBlockingQueue
2.在高负载的情况下,无界队列容易导致OOM,而OOM会导致所有请求都无法处理
3.因此强烈建议使用有界队列
1.使用有界队列,当任务过多时,线程池会触发拒绝策略
2.线程池默认的拒绝策略会抛出RejectedExecutionException,这是一个运行时异常,开发时很容易忽略
3.如果线程池处理的任务非常重要,可以自定义拒绝策略
1.使用ThreadPoolExecutor.execute()方法提交任务时,如果任务在执行过程中出现运行时异常
2.因此最稳妥的方法还是捕获所有异常并处理
try { // 业务逻辑 } catch (RuntimeException x) { // 按需处理 } catch (Throwable x) { // 按需处理 }
群内有技术大咖指点难题,还提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)
比你优秀的对手在学习,你的仇人在磨刀,你的闺蜜在减肥,隔壁老王在练腰, 我们必须不断学习,否则我们将被学习者超越!