菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
247
0

Java线程池

原创
05/13 14:22
阅读数 64156

利用Executors创建不同的线程池满足不同场景的需求

线程池的创建方式: Java基础二、多线程

 

1、Fork/Join框架

把大任务分割成若干小任务并行执行,最终汇总每个小任务结果后得到大任务结果的框架。

 

 

 2、Work-Stealing算法: 某个线程从其他队列里窃取任务来执行。

当某个线程闲置后,可以窃取其它线程池的任务来执行。

 

3、为什么要使用线程池

1) 降低资源的消耗。 (利用重复利用已经创建的线程,以降低线程创建和销毁造成的消耗)

2) 提高线程的可管理性

 

4、Executor框架

 

 J.U.C的三个Executor接口

1) Executor接口 运行新任务的简单接口,将任务提交和任务执行细节解耦。

2) ExecutorService接口: 具备管理执行器和任务生命周期的方法,提交任务机制更完善。

   subbit方法<T> Future<T> submit(Callable<T> task);

 3) ScheduledExecutorService接口  支持Future和定期执行任务

4) ThreadPoolExecutor类

 

 WorkQueue工作队列: 可以是LinkedBlockingQueue,SynchronousQueue等。

 5) ThreadPoolExecutor类

里面有一个Worker类,实现了Runnable接口

 

 构造函数中this.thread = getThreadFactory().newThread(this);

使用ThreadFactory创建线程。

 

ThreadPoolExecutor的构造函数

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

corePoolSize: 核心线程数量 

maximumPoolSize: 线程不够用时能够创建的最大线程数

workQueue: 任务等待队列

keepAliveTime: 线程池维护空闲线程的时间,超过等待时间,空闲线程被销毁。

threadFactory:创建新线程,Executors.defaultThreadFactory() 

handler: 线程池的饱和策略 

  AbortPolicy: 直接抛出异常,这是默认策略

  CallerRunsPolicy: 用调用者所在的线程来执任务

  DiscardOldestPloicy: 丢弃队列中靠最前的任务,并执行当前任务。

  DiscardPolicy: 直接丢弃任务

       实现RejectedExecutionHandler接口的自定义handler

 

新任务提交execute执行后的判断

 

 流程图如下:

 

 

线程池线程数量的存储

ThreadPoolExecutor类的ctl 变量

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

 

线程池的状态

RUNNING: 能接受新提交的任务,并且也能处理阻塞队列中的任务。

SHUTDOWN: 不再接受新提交的任务,但可以处理存量任务。

STOP:  不再接受新提交的任务,也不处理存量任务。

TIDYING: 所有的任务都已终止。

TERMINATED: terminated()方法执行完后进入该状态。

线程池的状态转换图

 

 

工作线程的生命周期

 

线程池的大小如何选定

CPU密集型: 线程数=按照核数或者 核数+1设定

I/O密集型: 线程数= CUP核数 * (1 + 平均等待时间/平均工作时间)

发表评论

0/200
247 点赞
0 评论
收藏