线程池原理分析

Java中提供的线程池的API

1、Executors中提供了几个线程池的工厂方法:

newFixedThreadPool:该方法返回一个固定数量的线程池,线程数不变,当有一个任务提交时,若线程池中空闲,则立即执行,没有,就被暂时缓存到一个任务队列中,等待有空闲到线程去执行。

newSingleThreadPool:创建一个线程的线程池,若空闲则执行,若没有空闲线程则暂缓在任务队列中。

newCachedThreadPool:返回一个可根据实际情况调整线程个数的线程池,不限制最大线程的数量,若有空闲的线程则去执行任务,若没有任务则不创建线程。并且每个空闲的线程会在60秒后自动回收。

newScheduledThread:创建一个可以指定线程的数量的线程池,但是这个线程池还带有延迟和周期性执行任务的功能,类似定时器。

2、创建线程池

private static ExecutorService executorService = Executors.newFixedThreadPool(10);

如上代码所示,初始化线程池 ThreadPoolExecutor,需要初始化的几个属性如下:
corePoolSize:核心线程数量

maximumPoolSize:最大线程数量

keepAliveTime:超时时间,超出核心线程数量以外的线程剩余的存活时间

TimeUnit: 超时时间的单位(ms/s)
workQueue:保存执行任务的队列

threadFactory:创建新线程使用的工厂

handler:当任务无法执行的时候的处理方式

3、阻塞队列

参数workQueue队列指的是用以存储已提交但是未执行的任务,可以作为workQueue队列BlockingQueue接口的实现类有如下几种实现:

1)直接提交队列--SynchronousQueue:

        任务数大于maximumPoolSize----->拒绝策略

        该队列不会真的保存任务,而是直接交给worker线程执行,如果没有可用的线程就直接创建线程执行,如果worker线程已经超过了maximumPoolSize,就执行拒绝策略;

2)有界的任务队列--ArrayBlockingQueue:

        任务加到corePoolSize---->ArrayBlockingQueue---->maximumPoolSize---->拒绝策略

        指定队列的大小,有新任务进来,如果当前worker线程数量小于corePoolSize,优先创建线程执行;如果大于corePoolSize,先保存到ArrayBlockingQueue队列中;当超过了ArrayBlockingQueue设定的大小,判断worker线程数如果小于maximumPoolSize,就创建线程执行;如果大于maximumPoolSize,就执行拒绝策略;

3)无界的任务队列--LinkedBlockingQueue:

        任务corePoolSize---->LinkedBlockingQueue----->直到耗尽了系统资源

        除非系统资源耗尽,否则不存在入队失败的情况;当有新任务进来,如果worker线程数小于corePoolSize就直接创建线程执行;如果大于corePoolSize就很直接加入到LinkedBlockingQueue中;

4)优先任务队列--PriorityBlockingQueue:

        该队列可以按照优先级,设置任务被执行的顺序;其他的同ArrayBlckingQueue执行一致;

4、向任务执行

executorService.execute(new ExecutorsServiceDemo())
public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

ctl的作用

是一个原子类,主要的作用就是保存线程的数量和线程池的状态,因为是int类型的,它的数值就是32位,高3位保存运行的状态,低29位来保存线程的数量。

worker工作线程的5种状态:

RUNNING【-1<< 29】:接收新任务,并执行队列中的任务

SHUTDOWN【0 << 29】:不接收新任务,但是执行队列中的任务

STOP【1<<29】:不接收新任务,不执行队列中的任务,中断正在执行的任务。

TIDYING【2<< 29】:所有的任务都已经结束,线程的数量为0,处于该状态的线程池即将调用terminated()方法。

TERNINATED【3<<29】:terminated()方法执行完成

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值