Java 多线程线程池-ThreadPoolExecutor分析

0.合理使用线程池的好处

降低资源消耗--通过重复利用已创建的线程,降低线程的创建和销毁造成的消耗
提高响应速度-当任务到达时,任务可以不用等待线程创建就能立即执行

提高线程的可管理性-线程是稀缺资源,如果无限制的创建线程,不仅会消耗系统的资源,还会降低系统的稳

定性,使线程可以进行统一的分配、调优和监控

 

 

 

 

1.线程池状态

2.线程池ThreadPoolExecutor类主要成员变量的含义

成员变量含义
private final BlockingQueue<Runnable> workQueue任务缓存队列,用来存放等待执行的任务
private final ReentrantLock mainLock = new ReentrantLock();线程池状态发生改变,都要使用这个锁
private final HashSet<Worker> workers = new HashSet<Worker>();用来存放工作集
private int largestPoolSize;线程池中曾经存在过的最大线程数
private long completedTaskCount;线程池已经完成的所有任务记录数
private volatile ThreadFactory threadFactory;线程工厂,用来创建线程
private volatile RejectedExecutionHandler handler;任务拒绝策略
private volatile long keepAliveTime;

当线程数大于corePoolSize时,

线程池中线程的最大存活时间

private volatile int corePoolSize;

核心线程池大小,当线程池中的线程数量大于corePoolSize时

会把任务放到任务缓存队列中去

private volatile int maximumPoolSize;

线程池最大容忍的线程大小,即当任务缓存队列已满来的新任务会创建新的线程去处理

private volatile boolean allowCoreThreadTimeOut;是否允许核心线程设置存活时间

 

3.线程池的执行流程

 

4.线程池的任务缓存队列以及排队策略

类型作用
ArrayBlockingQueue基于数组的先进先出队列,在使用的时候必须指定大小
LinkedBlockingQueue基于链表的先进先出队列,如果没有指定大小,默认Integer.MAX_VALUE
synchronousQueue不会保存队列,直接创建新的线程去执行任务

 

 

 

 

 

5.线程池的拒绝策略

策略说明
ThreadPoolExecutor.AbortPolicy丢弃任务并抛出RejectedExecutionException异常
ThreadPoolExecutor.DiscardPolicy也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy调用线程处理该任务

 

6.线程池的关闭

方法说明
shutdown()

不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务

shutdownNow()立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务

 

注意:

  1) Since1.6 通过方法 public void allowCoreThreadTimeOut(boolean value) 设置核心线程允许设置存货时间

  2) 通过方法 public void setRejectedExecutionHandler(RejectedExecutionHandler handler)设置拒绝策略

7.自定义线程池

package com.roger.threadpool;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class CustomThreadPoolExecutor {

    private ThreadPoolExecutor threadPoolExecutor;


    /**
     * 线程池的初始化
     *   核心线程数 10
     *   最大线程数 30
     *   线程空闲时间 30分钟
     *   有界队列
     *   自定义线程工厂类
     *   自定义拒绝策略:
     *      1) 当提交的任务超过  maximumPoolSie + 队列的容量时
     *      2) 线程池中没有空闲线程
     *   此时:会把超过的任务交给这个类进行处理
     */
    public void init(){
        threadPoolExecutor = new ThreadPoolExecutor(
                10,
                30,
                30,
                TimeUnit.MINUTES,
                new ArrayBlockingQueue<Runnable>(10),
                new CustomThreadFacotry(),
                new CustomRejectedExceptionHandler()
        );
    }

    public ExecutorService getCustomThreadPoolExecutor(){
        return this.threadPoolExecutor;
    }

    public void destory(){
        if(threadPoolExecutor != null){
            //等待所有正在执行线程执行完,才会终止
            threadPoolExecutor.shutdown();
        }
    }

    private class CustomThreadFacotry implements ThreadFactory {

        private AtomicInteger count = new AtomicInteger(0);

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            String threadName = CustomThreadPoolExecutor.class.getSimpleName() + "-" + count.getAndIncrement();
            thread.setName(threadName);
            return thread;
        }
    }

    private class CustomRejectedExceptionHandler implements RejectedExecutionHandler{

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            try {
                // 核心改造点,由blockingqueue的offer改成put阻塞方法
                executor.getQueue().put(r);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
package com.roger.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

public class CustomThreadPoolMain {

    public static void main(String[] args) {
        CustomThreadPoolExecutor customThreadPoolExecutor = new CustomThreadPoolExecutor();
        customThreadPoolExecutor.init();


        ExecutorService executorService = customThreadPoolExecutor.getCustomThreadPoolExecutor();

        for (int i =0; i < 100; i ++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getName() + " Task running >>>>  ");
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值