java线程池详解及实例

tech2024-08-08  50

作用

降低资源消耗。提高响应速度。提高线程的可管理性。

参数说明

corePoolSize // 核心线程池大小

maximumPoolSize // 最大线程池大小

keepAliveTime // 线程最大空闲时间

unit // 时间单位

TimeUnit.MILLISECONDS (毫秒) TimeUnit.SECONDS () TimeUnit.MINUTES (分钟) TimeUnit.HOURS (小时) TimeUnit.DAYS ()

workQueue // 线程等待队列

SynchronousQueue(直接握手队列) LinkedBlockingQueue(无界队列) ArrayBlockingQueue(有界队列) PriorityBlockingQueue(优先级队列)

threadFactory // 线程创建工厂(有默认)

handler // 拒绝策略(有默认)

AbortPolicy策略:该策略会直接抛出异常,阻止系统正常工作; CallerRunsPolicy策略:如果线程池的线程数量达到上限,该策略会把任务队列中的任务放在调用者线程当中运行; DiscardOledestPolicy策略:该策略会丢弃任务队列中最老的一个任务,也就是当前任务队列中最先被添加进去的,马上要被执行的那个任务,并尝试再次提交; DiscardPolicy策略:该策略会默默丢弃无法处理的任务,不予任何处理。当然使用此策略,业务场景中需允许任务的丢失;

线程池的逻辑分析 图:

Created with Raphaël 2.2.0 有任务提交 初始线程数满? 队列数满? 进入workQueue等待 最大线程池满? 拒绝策略 创建新的线程 执行任务 结束 yes no yes no yes no

伪代码:

有任务提交--> if(corePoolSize 没满){ 创建新的线程执行任务 } else if(workQueue 没满) { 进入workQueue等待 } else if(maximumPoolSize 没满){ 创建新的线程执行任务 } else { handler拒绝策略 }

线程池的监控

getLargestPoolSize():曾经最大线程数量 getPoolSize():现有线程数量 getTaskCount():总需要执行的任务数量 getActiveCount():正在工作的线程数量 getCompletedTaskCount():已完成的任务数量

例子

// 初始化线程池 private static final ThreadPoolExecutor THREAD_POOL = initThreadPool(); // 测试main public static void main(String[] args) { for (int i = 0; i < 5; i++) { int number = i; THREAD_POOL.execute(() -> { // 要用线程执行的代码 System.out.println(Thread.currentThread().getName() + " 打印了 " + number); }); } // THREAD_POOL.shutdown(); 此句是关闭线程池,在项目中一般不用关闭. } private static ThreadPoolExecutor initThreadPool() { // 获取电脑CPU核数 int cpuCount = Runtime.getRuntime().availableProcessors(); // 初始线程数 int corePoolSize = cpuCount; // 最大线程池大小 int maximumPoolSize = 30; // 线程最大空闲时间 long keepAliveTime = 60; // 时间单位: 秒 TimeUnit unit = TimeUnit.SECONDS; // 线程等待队列 SynchronousQueue<Runnable> workQueue = new SynchronousQueue<>(); // 线程序列 AtomicInteger atomicInteger = new AtomicInteger(1); // 线程工厂 ThreadFactory namedThreadFactory = (Runnable r) -> new Thread(r, "采集线程-" + atomicInteger.getAndIncrement()); // 创建线程池 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, namedThreadFactory); // 预启动线程池 threadPool.prestartAllCoreThreads(); // 返回线程池. return threadPool; }

其它4种常见的线程池

可缓存线程池

无上限, 优先使用空线程, 无空线程就创建新线程使用 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); cachedThreadPool.execute(Runnable runnable)

可重用固定个数的线程池

有固定上限 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(int n) fixedThreadPool.execute(Runnable runnable)

定长线程池

可以设定多久后, 每多久执行一次 ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(int n) // 延迟1秒后每3秒执行一次 scheduled.scheduleAtFixedRate(Runnable runnable, 1, 3,TimeUnit.SECONDS) // 延迟1秒后执行 scheduled.schedule(Runnable runnable, 1, TimeUnit.SECONDS)

一个单线程化的线程池

它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行 ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); singleThreadExecutor.execute(Runnable runnable)
最新回复(0)