Java线程池总结之从使用探究源码实现

先回顾下类关系图:
线程池相关类结构图

一般的使用方式:这里不用Executors帮助类,而是构建自己的线程池:

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2016/7/21.
 */
public class ThreadPoolUtil {
   

    private static ThreadPoolUtil threadPoolUtil;
    private static ThreadPoolExecutor poolExecutor;

    //核心线程数
    private int corePoolSize = 5;
    //最大线程数据
    private int maximumPoolSize = 5;

    private ThreadPoolUtil() {

        poolExecutor = new ThreadPoolExecutor(corePoolSize,
                maximumPoolSize,
                0L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>());
    }

    public static ThreadPoolUtil newInstance() {

        if (threadPoolUtil == null) {
            synchronized (ThreadPoolUtil.class) {
                if (threadPoolUtil == null) {
                    threadPoolUtil = new ThreadPoolUtil();
                }
            }
        }
        return threadPoolUtil;

    }

    public void execute(Runnable task) {
        poolExecutor.execute(task);
    }

    /**
     * 执行需要返回结果的任务
     */
    public Future<Runnable> execute(Callable<Runnable> task) {
        return poolExecutor.submit(task);
    }
}

简单的使用方式:

ThreadPoolUtil poolUtil = ThreadPoolUtil.newInstance();
poolUtil.execute(new Runnable() {
  ...});
poolUtil.execute(new Runnable() {
  ...});
poolUtil.execute(new Runnable() {
  ...});
.
.
.

首先了解下构造函数的各个参数含义:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

corePoolSize : 核心线程数,也就是线程池中保持存活的线程有多少,包括正在执行任务和空闲的。
maximumPoolSize:最大线程数,也就是核心线程数全部都在执行任务,没有空闲的出来,且等待队列也已经装载满了,然后后又有新的任务需要执行,这时就会开启新的线程来执行,但总线程数:corePoolSize+newThreadSize <= maximumPoolSize。
keepAliveTime:多出的空闲线程存活的时间,也就是当前线程数大于核心线程数的这部分: nowThreadSize(当前线程总数) - corePoolSize 这部分的线程。
unit :线程存活的时间单位:有秒、分、时等等
workQueue :存放等待执行的任务队列
threadFactory :创建线程的工厂类、一般使用默认Executors.defaultThreadFactory()。
handler:处理多出的任务策略,也就是等待队列已满,最大线程数量中都没有空闲线程,此时还是有任务提交过来,就需要进行处理。有抛异常、不处理等。


提出问题:既然已经规定了核心线程数和最大线程数,当我们不断向线程池提交任务的时候,内部是否会进行开启核心线程数的线程进行并行执行任务,当再有任务提交的时候,就会放到等待队列中,直到队列满了,再开启线程来执行,当线程数据大于maximumPoolSize时,是否进行handler策略处理。

代码验证四部曲:

1.当需执行任务数小于核心线程数,池中的线程是否一开始就维持核心线程数的数量。
2.当执行任务数大于核心线程数,该任务是暂存在队列中还是立即开启新的线程执行。
3.当池中线程数量达到最大线程数时,且无空闲线程,队列也已经满了,此时还有新的任务提交过来,是否执行处理策略。

首先看已修改的类:

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2016/7/21.
 */
public class ThreadPoolUtil {
   

    private static ThreadPoolUtil threadPoolUtil;
    private static ThreadPoolExecutor poolExecutor;

    //核心线程数
    private int corePoolSize = 2;
    //最大线程数据
    private int maximumPoolSize = 5;
    //创建等待队列大小而2
    private LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(2);

    private ThreadPoolUtil() {

        poolExecutor = new ThreadPoolExecutor(corePoolSize,
                maximumPoolSize,
                0L,
                TimeUnit.SECONDS,
                queue,
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
    }

    public static ThreadPoolUtil newInstance() {

        if (threadPoolUtil == null) {
            synchronized (ThreadPoolUtil.class) {
                if (threadPoolUtil == null) {
                    threadPoolUtil = new ThreadPoolUtil();
                }
            }
        }
        return threadPoolUtil;

    }

    public void execute(Runnable task) {
        poolExecutor.execute(task);
    }

    /**
     * 执行需要返回结果的任务
     */
    public Future<Runnable> execute(Callable<Runnable> task) {
        return poolExecutor.submit(task);
    }

    /**
     * 获取当前执行任务的线程数
     * @return
     */
    public int getCurrentThreadNum(){
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值