博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java 线程池
阅读量:7174 次
发布时间:2019-06-29

本文共 3372 字,大约阅读时间需要 11 分钟。

一、什么时候使用线程池

(1)、减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

(2)、可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机),具体可以使用Runtime.getRuntime().availableProcessors()查看虚拟机返回可用处理器的数量()。

二、线程池状态

(1)、RUNNING : 当创建线程池后,初始时,线程池处于RUNNING状态。

(2)、SHUTDOWN : 如果调用了shutdown()方法,则线程池处于SHUTDOWN状态,此时线程池不能够接受新的任务,它会等待所有任务执行完毕。
(3)、STOP : 如果调用了shutdownNow()方法,则线程池处于STOP状态,此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务。
(4)、TIDYING : 所有任务已终止,workerCount为零,线程转换到状态TIDYING,运行terminate()方法。
(5)、TERMINATED : 当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为TERMINATED状态。

三、初始化参数

(1)、corePoolSize : 线程核心线程数,当有任务进来时,当前运行的线程数量小于核心线程就会在创建线程,当前线程等于核心线程数时,任务就会被放入队列里面,请参照 (5)。

(2)、maximumPoolSize : 线程池中允许的最大线程数,当线程池的线程 >= 核心线程数时,并且队列已经放满了任务,这时线程池就会在创建线程去执行任务。
(3)、keepAliveTime : 当前线程数大于核心线程数时,线程池就会找机会干掉多余的线程,当没有任务可以执行时,线程池会给全部线程定一个等待时间,如果过了这个时间,没有获得任务进来就直接干掉线程 (当前线程数等于或多于核心线程数时,线程池首选将任务加入队列,而不添加新的线程)。
(4)、unit : keepAliveTime的时间单位。
(5)、workQueue : 在执行任务之前用于保留任务的队列,(当前线程数大于等于核心线程数时,再有任务进来就会被放到队列里面)。
常用队列 :
(1)、LinkedBlockingQueue,LinkedBlockingQueue是一个无界队列,存储方式使用的是链表
(1)、ArrayBlockingQueue,ArrayBlockingQueue是一个有界队列,存储方式使用的是数组
(1)、SynchronousQueue,SynchronousQueue是一个同步队列没有任何内部容量,直接将任务交给线程,(SynchronousQueue通常要求最大线程数是无界的以避免拒绝新提交的任务)。

四、使用

官方文档强烈建议程序员使用较为方便的 Executors 工厂方法 Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)(固定大小线程池)和 Executors.newSingleThreadExecutor()(单个后台线程)

五、运行流程

(1)、当提交一个任务!

public void execute(Runnable command) {

if (command == null)        throw new NullPointerException();    int c = ctl.get();    /*     先判断是否工作线程是否小于核心线程,如果小于就添加到调用添加工作方法。     添加成功就返回。     如果当前线程大于等于核心线程就将任务放进队列里面。    */    if (workerCountOf(c) < corePoolSize) {        if (addWorker(command, true))            ...    }    if (isRunning(c) && workQueue.offer(command)) {        ...    }}

(2)、执行任务

private boolean addWorker(Runnable firstTask, boolean core) {

...    boolean workerStarted = false;    boolean workerAdded = false;    Worker w = null;    try {        final ReentrantLock mainLock = this.mainLock;        /*            创建一个工作线程,将任务放进去        */        w = new Worker(firstTask);        final Thread t = w.thread;        if (t != null) {            mainLock.lock();            try {                // Recheck while holding lock.                // Back out on ThreadFactory failure or if                // shut down before lock acquired.                int c = ctl.get();                int rs = runStateOf(c);                if (rs < SHUTDOWN ||                    (rs == SHUTDOWN && firstTask == null)) {                    if (t.isAlive()) // precheck that t is startable                        throw new IllegalThreadStateException();                        /*                            将所有工作放到Set集合,进行管理                        */                    workers.add(w);                    int s = workers.size();                    if (s > largestPoolSize)                        largestPoolSize = s;                    workerAdded = true;                }            } finally {                mainLock.unlock();            }            if (workerAdded) {                 /*                    执行任务线程                 */                t.start();                workerStarted = true;            }        }    } finally {        if (! workerStarted)            addWorkerFailed(w);    }    return workerStarted;}

只想写一点文章希望大家,多多指点。

转载地址:http://xwdzm.baihongyu.com/

你可能感兴趣的文章
Hive 数据倾斜总结
查看>>
mysql查询结果处理
查看>>
扫描识别控件Dynamic Web TWAIN v12.3.1发布,更新服务证书丨附下载
查看>>
VintaSoft PDF插件VintaSoftPDF.NET Plug-in更新至v5.6,新增多页查看模式
查看>>
windows环境中不重启电脑杀死占用某个端口的进程
查看>>
“90+68”的完美转变
查看>>
Kubernetes上的负载均衡详解
查看>>
centos7格式化大于2T的硬盘
查看>>
为什么要进行项目总结呢?又如何进行项目总结呢?
查看>>
iOS——重写Cell分割线
查看>>
window与linux下,php的redis扩展安装
查看>>
VirtualBox虚拟机网络设置
查看>>
Mongodb 之 安全权限控制
查看>>
httpclient发送网络请求
查看>>
可自动切换登录不同系统测试实例
查看>>
jQuery Validate
查看>>
Building IKEv1 and IKEv2 on CentOS 7
查看>>
Zabbix server is not running:zabbix access denied
查看>>
我的友情链接
查看>>
linux下的软硬链接
查看>>