栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java线程池的原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java线程池的原理

前言 为什么要用线程池

在一个进程中,线程是一种非常稀缺的资源。频繁地创建或销毁线程也是一个消耗资源的过程,所以用线程池,可以减少以上的过程。
优势:

    线程复用,减少创建和销毁,提高性能响应快可以统一管理和监控
什么时候用
    任务量大和需要异步每个任务处理时间较短
原理 参数

线程池七大参数:

    corePoolSize(核心池大小)maximumPoolSize(最大线程池大小)keepAliveTime(存活时间)unit(时间单位)workQueue(工作队列)threadFactory(线程工厂)handler(拒绝策略)
原理图

说明

这里将设定线程池的参数:核心数=2,最大数=3,队列数=5

    如果核心池为空,则有任务进入,马上在核心池中进行如果核心池已经满了,则还有任务进入,非核心池将开辟线程进行处理如果核心池和非核心池都满了,则还有任务的,进入队列等待如果队列也满了,则根据拒绝策略,对想要进入队列的任务进行处理,默认的就是直接报异常
    四个拒绝策略:
    AbortPolicy:
    直接抛异常
java.util.concurrent.RejectedExecutionException: Task com.company.Thread.MyTask@135fbaa4 rejected from java.util.concurrent.ThreadPoolExecutor@45ee12a7

DiscardPolicy:
丢弃任务,但是不抛出异常。

CallerRunsPolicy:
丢弃队列最前面的任务,然后重新提交被拒绝的任务

for (int i = 0; i < 8; i++) {
    try {
        threadPoolExecutor.execute(new MyTask(i));
    }
    catch (Exception e){
        e.printStackTrace();
    }
}
threadPoolExecutor.execute(new MyTask(8));

#######################

pool-1-thread-3--7:done!
pool-1-thread-2--1:done!
pool-1-thread-1--0:done!
pool-1-thread-2--4:done!
pool-1-thread-3--3:done!
pool-1-thread-1--5:done!
pool-1-thread-2--6:done!
pool-1-thread-3--8:done!

可以看出8才是最后提交的,但是却有8的任务完成,其中2不见了,因为2是在队列的最前面。

DiscardOldestPolicy:
调用线程处理该任务

代码分析

构造函数的七大参数

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

有四个可选策略

    CallerRunsPolicyAbortPolicyDiscardPolicyDiscardOldestPolicy
    默认策略:AbortPolicy()
private static final RejectedExecutionHandler defaultHandler =
    new AbortPolicy();
...
public static class CallerRunsPolicy implements RejectedExecutionHandler 
...
public static class AbortPolicy implements RejectedExecutionHandler
...
public static class DiscardPolicy implements RejectedExecutionHandler
...
public static class DiscardOldestPolicy implements RejectedExecutionHandler
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
...
public void execute(Runnable command) {
    // 命令为空抛异常
    if (command == null)
        throw new NullPointerException();
    // 原子性cas,线程安全
    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);
}
测试

测试代码:

public class threadpool {
    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor =
                new ThreadPoolExecutor(2, 3, 60, TimeUnit.SECONDS, new ArrayBlockingQueue(5), Executors.defaultThreadFactory());
//        ExecutorService e1 = Executors.newCachedThreadPool();
//        ExecutorService e2 = Executors.newFixedThreadPool(10);
//        ExecutorService e3 = Executors.newSingleThreadExecutor();


        for (int i = 0; i < 9; i++) {
            try {
                threadPoolExecutor.execute(new MyTask(i));
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }


        Queue queue = threadPoolExecutor.getQueue();

        for (int i = 0; i < 10; i++) {
            System.out.println("核心数:" + threadPoolExecutor.getCorePoolSize());
            System.out.println("最大数:" + threadPoolExecutor.getMaximumPoolSize());
            System.out.println("池化数:" + threadPoolExecutor.getPoolSize());
            System.out.println("队列数:" + queue.size());
            System.out.println("默认策略:" + threadPoolExecutor.getRejectedExecutionHandler());
            Thread.sleep(60000L);
            System.out.println("*************************************");
        }

        threadPoolExecutor.shutdown();
    }
}

class MyTask implements Runnable{
    int i = 0;

    public MyTask(int i){
        this.i = i;
    }

    @Override
    public void run() {
        try{
            Thread.sleep(60000L);
            System.out.println(Thread.currentThread().getName() + "--" + i + ":done!");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

以下结果可以看出,在核心池和非核心池都满了,和队列也满的情况下,在加入任务,就会触发拒绝策略,报异常。
每完成一个任务,都将队列的任务往核心池仍,直到队列空了。
结果:

java.util.concurrent.RejectedExecutionException: Task com.company.Thread.MyTask@135fbaa4 rejected from java.util.concurrent.ThreadPoolExecutor@45ee12a7[Running, pool size = 3, active threads = 3, queued tasks = 5, completed tasks = 0]
	at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
	at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
	at com.company.Thread.threadpool.main(threadpool.java:17)
核心数:2
最大数:3
池化数:3
队列数:5
默认策略:java.util.concurrent.ThreadPoolExecutor$AbortPolicy@2503dbd3
*************************************
pool-1-thread-1--0:done!
pool-1-thread-2--1:done!
pool-1-thread-3--7:done!
核心数:2
最大数:3
池化数:3
队列数:2
默认策略:java.util.concurrent.ThreadPoolExecutor$AbortPolicy@2503dbd3
pool-1-thread-1--2:done!
*************************************
核心数:2
最大数:3
池化数:3
pool-1-thread-3--4:done!
pool-1-thread-2--3:done!
队列数:1
默认策略:java.util.concurrent.ThreadPoolExecutor$AbortPolicy@2503dbd3
*************************************
核心数:2
最大数:3
pool-1-thread-1--5:done!
pool-1-thread-3--6:done!
池化数:2
队列数:0
默认策略:java.util.concurrent.ThreadPoolExecutor$AbortPolicy@2503dbd3
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/723750.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号