ThreadPoolExecutor 的常用用法
来源:互联网 发布:台北房价知多少 编辑:程序博客网 时间:2024/06/07 20:33
ThreadPoolExecutor 的常用用法
平常工作中遇到并发场景的解决方案,一般会将大任务拆分成相互独立的小任务,然后将这些小的任务提交给线程池
去执行。
线程池
的具体实现大致有Executors
的newFixedThreadPool()
,newCachedThreadPool()
等等方法。但通过看它们的底层实现都是去new ThreadPoolExecutor()
,且在工作中采用这种偏底层的实现方式也更多些,对自己写的并发程序能有更好的控制。
下面以简单程序的形式展现new ThreadPoolExecutor()
的用法:
package org.zeng.test.concurrent;import java.util.concurrent.*;import java.util.concurrent.atomic.AtomicInteger;/** * Created by liu shuangzeng on 2017/11/11 21:14. */public class ThreadPoolTest { /** * corePoolSize: 核心线程数;如果不设置AllowCoreThreadTimeOut=true,则不会被销毁,即使处于闲置状态 * maximumPoolSize: 最大线程数;= 核心线程数 + 非核心线程数 * keepAliveTime, unit: 非核心线程的闲置后的生命周期 * BlockingQueue: 阻塞队列;线程池提交任务时先会创建核心线程,如果核心线程不够了,则会将任务塞到队列中;如果队列也满了,则开始创建非核心线程处理任务; * 如果非核心线程也不够用了,则新来的任务会进入 RejectedExecutionHandler 处理。。 * 关于 BlockingQueue,虽然它是 Queue 的子接口,但是它的主要作用并不是容器,而是作为线程同步的工具,它有一个特征, * 当生产者试图向 BlockingQueue 放入(put)元素,如果队列已满,则该线程被阻塞;当消费者试图从 BlockingQueue 取出(take)元素,如果队列已空,则该线程被阻塞。 * @param size * @return */ public static ThreadPoolExecutor getThreadPool(int size) { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(size, 10, 30, TimeUnit.DAYS, new LinkedBlockingDeque<Runnable>(5), new ThreadFactory() { private final AtomicInteger atomicInteger = new AtomicInteger(); @Override public Thread newThread(Runnable r) { return new Thread(r, "test-" + atomicInteger.incrementAndGet()); } }, new RejectedExecutionHandler() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { System.out.println("队列满啦,而且线程数量达到最大数量啦!"); try { executor.getQueue().put(r); System.out.println("卡住了嘛?"); } catch (Exception e) { System.out.println("塞入队列异常啦!"); } System.out.println("塞进队列成功!"); } }); return threadPoolExecutor; } public static void main(String args[]) throws Exception{ ThreadPoolExecutor threadPoolExecutor = getThreadPool(3); for (int i = 0; i < 20; i++) { threadPoolExecutor.execute(new Runnable() { @Override public void run() { work(); } });// Future future = threadPoolExecutor.submit(new Runnable() {// @Override// public void run() {// work();// }// });// future.get(); //会阻塞当前线程 System.out.println("当前队列的剩余容量:" + threadPoolExecutor.getQueue().remainingCapacity()); } } public static void work() { try{ System.out.println("线程: " + Thread.currentThread().getName() + "进来啦!"); Thread.sleep(1000l); } catch (Exception e) { } }}
new ThreadPoolExecutor()
的参数比较多,但理解了:线程池提交任务时先会创建核心线程,如果核心线程不够了,则会将任务塞到队列中;如果队列也满了,则开始创建非核心线程处理任务; 如果非核心线程也不够用了,则新来的任务会进入RejectedExecutionHandler处理
这个过程也就不那么难记忆和使用了。
注意的点:
1. 如果不为BlockingQueue指定容量的化,它默认容量是Integer.MAX_VALUE
,此时若maximumPoolSize
> corePoolSize
,那么基本上永远也不会去创建非核心线程,除非你的任务真的塞满了Integer.MAX_VALUE
大小的队列.
2. 一种可以通俗理解的优先级: 核心线程 > 队列 > 非核心线程 > RejectedExecutionHandler
阅读全文
1 0
- ThreadPoolExecutor 的常用用法
- ThreadPoolExecutor用法
- ThreadPoolExecutor优势与用法
- 1. ThreadPoolExecutor的一个常用的构造方法
- threadPoolExecutor 中的 shutdown() 、 shutdownNow() 、 awaitTermination() 的用法和区别
- ThreadPoolExecutor线程池用法研究
- ThreadPoolExecutor的使用
- Java的ThreadPoolExecutor(二)
- ThreadPoolExecutor的工作机制
- ThreadPoolExecutor的作用
- ThreadPoolExecutor 的使用详解
- ThreadPoolExecutor的使用
- 关于ThreadPoolExecutor的解析
- ThreadPoolExecutor的跟踪
- ThreadPoolExecutor的使用
- ThreadPoolExecutor的参数介绍
- ThreadPoolExecutor的简单例子
- Java中的线程池——3种常用的ThreadPoolExecutor
- 42. Trapping Rain Water
- bigdata-18
- bigdata-19
- Maven setting.xml
- bigdata-20
- ThreadPoolExecutor 的常用用法
- 移动互联网实时视频通讯之视频采集
- Ajax
- hdoj no.2002
- SDNU做题总结
- 如何将一个Maven项目转化成一个Eclipse项目
- Anniversary party (树形dp)
- Eclipse强制关闭导致无法再次启动的解决方法
- Http中Get与Post的区别