文档章节

Executors线程池

Magic_锋
 Magic_锋
发布于 07/26 09:24
字数 1106
阅读 13
收藏 0
/**
 * Executors的好处:可创建固定数量线程的线程池,并可以重用线程池中的线程,减少创建对象, 销毁对象,节省资源
 * 并且支持线程定时,中断操作,可控制并发的线程数量
 * 而new Thread,在调用run方法后,如果里面的任务执行完毕, 则这个线程会自动关闭了,如果下次还想用
 * 则需要再次new Thread,重新创建, 不断创建的话, 会占用较多的资源,可能会造成oom,而且 每个线程不易于统一管理

 execute和submit比较
 * execute 执行不需要返回值的任务
 * submit 执行需要返回值的, 返回Future 对象,通过Future 的get方法获返回值,当调用get方法时,当前线程阻塞,直到任务完成
 *
 * 执行execute时,是在ThreadPoolExecutor这个类中,主要分为三步
 * 1.先判断当前线程数量是否大于核心线程数,如果小于,则创建线程开始执行任务,如果大于则进入BlockingQueue<Runnable> 队列 排队
 * 2.进入排队后,再次进行检查状态(因为有些线程步骤1检查后就死了,或者线程池关闭了),线程池若没有线程则创建新的线程, 线程池关闭,则回滚入队列
 * 3.如果队列满了, 无法进入队列,就尝试开启新的线程, 则判断如果线程池线程满了,也就是达到最大线程数,这时候就执行拒绝策略,
 *      如果开启新的线程成功,则就入新队列
  * 而在执行execute的三步中,最主要的方法就是addWorker----worker----getTask
 *
 *  new Thread().start()在一旦执行起来之后,只有在执行完毕后才线程才进入stop状态,不能再次start,如果想在重新复用,只能在
 *  runnable中下手,可以用死循环一直执行runnable.run的方法,在run的时候检查是否有新的任务进来, 有新任务,就执行新任务的run方法,
 *  如果有多个新任务, 就把多个任务的run串联起来,一个个的去执行,没有新任务的时候,就进入队列阻塞,
 *  Executors真正的最底层核心 就是这个
 */
public class ThreadPoolUtils {
    private ScheduledExecutorService scheduledExecutorService;
    private ExecutorService fixedThreadPool;

    /*--------------------------定时线程------------------------------------------------------------------*/
    /**
     * 开启固定数量线程的线程池
     * 也支持开启定时的线程池
     * 这里就传 1, 模拟只支持一个线程的线程池
     * @param runnable
     * @param start 开始几秒后执行第一次
     * @param delay 第一次之后,每次间隔时间delay后,执行下一次
     *              默认使用秒
     */
    public void startTimerPool(Runnable runnable,long start,long delay){
        scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleWithFixedDelay(runnable,start,delay, TimeUnit.SECONDS);
    }

    /**
     * 关闭定时的线程池
     */
    public void stopTimerPool(){
        scheduledExecutorService.shutdown();
        scheduledExecutorService = null;
    }

/*------------------------------------缓存线程,尽量少用--------------------------------------------------------*/

    /**
     * 创建缓存线程池,如果第一个线程任务完成, 则第二个线程会复用第一个线程,不会开启新线程,若第一个没完成,则第二个开启新线程去做
     * 超过60s没用的线程 会默认销毁
     * 适用于大流量但是周期短的异步处理
     *
     * 容易出现OOM,因为线程量大,每个线程占用内容多,就会出现oom
     * 1w个线程,每个线程占1M,这就是10G,但是电脑是8G的,就oom了
     *
     * 这种线程池 能少用就少用
     */
    public void startCachePool(Runnable... runnables){
        if (null == runnables)return;
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i=0;i<runnables.length;i++){
            executorService.execute(runnables[i]);
        }
    }

/*------------------------------------固定线程数量的线程池---------------------------------------------------*/
    /**
     * 创建定长的线程数的线程池,线程数量可控制的并发
     * 超过规定的并发量 就排队等着
     * 和CachedThreadPool不同,她的线程不会自动销毁
     *
     * @param poolSize 线程的数量
     */
    public void startFixedPool(int poolSize,Runnable... runnable){
         fixedThreadPool = Executors.newFixedThreadPool(poolSize);
        for (int i = 0;i<runnable.length;i++){
            fixedThreadPool.execute(runnable[i]);
        }
    }

    /**
     * 关闭线程池
     */
    public void stopFixedPool(){
        if (null == fixedThreadPool)return;
        fixedThreadPool.shutdown();
        fixedThreadPool = null;
    }

    /*------------------------------------单一线程数量的线程池---------------------------------------------------*/

    /**
     * 创建唯一的线程来执行,任务顺序执行,一个执行完后执行下一个
     * @param runnable
     */
    public void startSinglePool(Runnable runnable){
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.execute(runnable);
    }
}

 

© 著作权归作者所有

上一篇: Android常用算法
下一篇: UIAutomator2.0记录
Magic_锋
粉丝 0
博文 58
码字总数 35503
作品 0
东城
程序员
私信 提问
线程池ThreadPool

总共有5中线程池: ExecutorService pool1 = Executors.newFixedThreadPool(2);ExecutorService pool2 = Executors.newCachedThreadPool();ExecutorService pool3 = Executors.newScheduled......

刘付kin
2016/12/08
24
0
java多线程——线程池

为什么要使用线程池? (1)降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 (2)提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。 (3)提高线程的...

wjk_snail
2015/12/17
60
0
Java中线程池,你真的会用吗?

在《深入源码分析Java线程池的实现原理》这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理。 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建议这样使...

HollisChuang's Blog
2018/10/27
0
0
java四种线程池使用

Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 newFixedThreadPool 创...

方墨大师
2016/03/01
73
0
java并发框架Executor,便捷了并发编程开发

http://willsunforjava.iteye.com/blog/1631353 便于管理 并发操作,报表开发: JDK 线程池 Executors.newCachedThreadPool(); //带缓存的 不够时自动添加 Executors.newSingleThreadExecutor(......

noteman
2016/10/14
30
0

没有更多内容

加载失败,请刷新页面

加载更多

代理模式之JDK动态代理 — “JDK Dynamic Proxy“

动态代理的原理是什么? 所谓的动态代理,他是一个代理机制,代理机制可以看作是对调用目标的一个包装,这样我们对目标代码的调用不是直接发生的,而是通过代理完成,通过代理可以有效的让调...

code-ortaerc
19分钟前
2
0
学习记录(day05-标签操作、属性绑定、语句控制、数据绑定、事件绑定、案例用户登录)

[TOC] 1.1.1标签操作v-text&v-html v-text:会把data中绑定的数据值原样输出。 v-html:会把data中值输出,且会自动解析html代码 <!--可以将指定的内容显示到标签体中--><标签 v-text=""></......

庭前云落
51分钟前
7
0
VMware vSphere的两种RDM磁盘

在VMware vSphere vCenter中创建虚拟机时,可以添加一种叫RDM的磁盘。 RDM - Raw Device Mapping,原始设备映射,那么,RDM磁盘是不是就可以称作为“原始设备映射磁盘”呢?这也是一种可以热...

大别阿郎
今天
10
0
【AngularJS学习笔记】02 小杂烩及学习总结

本文转载于:专业的前端网站☞【AngularJS学习笔记】02 小杂烩及学习总结 表格示例 <div ng-app="myApp" ng-controller="customersCtrl"> <table> <tr ng-repeat="x in names | orderBy ......

前端老手
昨天
14
0
Linux 内核的五大创新

在科技行业,创新这个词几乎和革命一样到处泛滥,所以很难将那些夸张的东西与真正令人振奋的东西区分开来。Linux内核被称为创新,但它又被称为现代计算中最大的奇迹,一个微观世界中的庞然大...

阮鹏
昨天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部