多线程实现的方式
1、继承 Thread 类
通过继承 Thread 类,并重写 run 方法
2、实现 Runnable 接口
实现 Runnable 接口,并重写 run 方法
3、实现 Callable 接口
实现 Callable 接口,并重写 call 方法 1、Callable 接口有返回值,通过 FutureTask 可以获取返回值 2、与 Runnable 接口相比,Callable 接口可以抛出异常
4、通过线程池的方式实现多线程
java 中 ThreadPoolExecutor 实现多线程的方法
参数说明
corePoolSize
核心线程数,核心线程池的大小,当一个任务提交到线程池的时候,核心线程池会创建一个核心线程来执行任务
核心线程数会一直存活,即便没有任务需要执行的情况
当线程数小于核心线程数时,即便有线程空闲,线程池也会创建新线程处理
设置 allowsCoreThreadTimeOut=true(默认 false)时,核心线程会超时关闭
maximumPoolSize
最大线程数
当线程数>=corePoolSize,且任务队列已满时,线程池会创建新线程来处理任务
当线程数=maximumPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常
keepAliveTime
线程空闲时间
当线程空闲时间达到 keepAliveTime 时,线程会退出,直到线程数量=corePoolSize
如果 allowsCoreThreadTimeOut=true,则会知道线程数量=0
TimeUnit
时间单位
BlockingQueue
任务队列
核心线程数达到最大时,新任务会放在队列中排队进行等待
RejectedExecutionHandler
拒绝策略,当线程池的队列已经满了的情况下。新进入的任务添加到线程池的时候就会进行处理,JDk 默认有四种任务拒绝策略
AbortPolicy(默认): 默认的拒绝策略,会直接抛出 RejectedExecutionException 异常
DiscardPolicy: 当新任务被提交后直接被丢弃
DiscardOldestPolicy: 当新任务添加进线程池的时候,会放弃任务队列中的头节点,此时丢弃的是队列中存活时间最长的队列
CallerRunsPolicy: 该策略既不会抛弃任务,也不会抛出异常,而是将任务回推到调用者。"顾名思义,在饱和的情况下,调用者会执行该任务
用户自定义拒绝策略: 实现 RejectedExecutionHandler,并自己定义策略模式
线程池的执行原理
工作流程图如下(https://gitee.com/ycodingnow/blogimage/raw/master/image/20220609112305.png)
版权声明: 本文为 InfoQ 作者【jun】的原创文章。
原文链接:【http://xie.infoq.cn/article/73bca9d81f6eac4a9261b63b8】。文章转载请联系作者。
评论