线程池4--进阶(自定义线程池 + 线程池监控 + 线程池隔离)

1、自定义线程池

如何创建线程池,核心是创建线程的 api:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,  TimeUnit unit,
                   BlockingQueue workQueue, ThreadFactory threadFactory,
                   RejectedExecutionHandler handler) {
    

 

示例:

package javaThreadPoolTrain;

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

public class MyThreadPool {

    private ThreadPoolExecutor pool = null;


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


    public void init() {
        pool = new ThreadPoolExecutor(
                3,
                3,
                30,
                TimeUnit.MINUTES,
                new ArrayBlockingQueue(5),
                new CustomThreadFactory(),
                new CustomRejectedExecutionHandler());
    }


    public void destory() {
        if (pool != null) {
            pool.shutdownNow();
        }
    }


    private class CustomThreadFactory implements ThreadFactory {

        private AtomicInteger count = new AtomicInteger(0);

        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            String threadName = MyThreadPool.class.getName() + count.addAndGet(1);
            System.out.println(threadName);
            t.setName(threadName);
            return t;
        }
    }


    private class CustomRejectedExecutionHandler implements RejectedExecutionHandler {

        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            // 记录异常
            // 报警处理等
            System.out.println("error.............");
            throw new NullPointerException("enough");
        }
    }

//
//    public static void test1() {
//        throw new NullPointerException("test");
//    }


    public static void main(String[] args) {
        try {
            System.out.println("hello");
            MyThreadPool myThreadPool = new MyThreadPool();
            myThreadPool.init();
            ExecutorService pool = myThreadPool.getCustomThreadPoolExecutor();
            for (int i = 1; i < 10; i++) {
                System.out.println("提交第" + i + "个任务!");
                pool.execute(new Runnable() {
                    public void run() {
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("running=====");
                    }
                });

            }
            //myThreadPool.destory();
        } catch (Exception e) {
            System.out.println("ss" + e);
        }
    }
}


 

 

2、 线程池监控

线程怎么说都是稀缺资源,对线程池的监控可以知道自己任务执行的状况、效率等。

2.1 java 内部提供的线程池指标 

线程池4--进阶(自定义线程池 + 线程池监控 + 线程池隔离)_第1张图片

具体函数解析:

getCorePoolSize: 或者配置的核心线程数
getMaximumPoolSize: 或者最大线程数
getKeepAliveTime : 获取线程最长的休眠时间 
getQueue: 获取工作队列
getThreadFactory(): 获取构建新线程的线程工厂类
getRejectedExecutionHandler():
getPoolSize(): 获取线程池中当前的线程数;
getActiveCount: 获取线程池中当前活跃的处于工作状态的线程数
getLargestPoolSize:获取线程池存活历史期间创建过的最大的线程数
getTaskCount:返回线程池总共执行过的任务数(包括完成的、正在执行的,以及还在队列中的)
getCompletedTaskCount:返回线程池总共完成过的任务数

对于这些指标,我们是可以通过metric 采集的方式动态采集出来,做到图表里,偏于我们实时查看线程池的使用情况,及时发现问题并且解决。

 

 

3、线程池配置动态修改技术

对于线程池,java 内部也提供了很多接口用于动态的修改线程池的配置,用于在线程池资源不足时,可以增加资源或者减少资源等

setKeepAliveTime:
setMaximumPoolSize:
setCorePoolSize
setRejectedExecutionHandler
setThreadFactory

最常用的应该就是set 核心线程数、最大线程数以及 线程最大存活时间

扩展:

除了在代码中显示触发一些条件进行set 外,我们还可以再外部动态的去修改线程池的参数,如通过zk 回调的方式,通过rpc 请求的方式等等

 

 

4、线程池隔离技术

线程池看似很美好,但也会带来一些问题。

如果我们很多业务都依赖于同一个线程池,当其中一个业务因为各种不可控的原因消耗了所有的线程,导致线程池全部占满。

这样其他的业务也就不能正常运转了,这对系统的打击是巨大的。对于不同的业务,我们需要做到线程池的隔离。

 

 

参考文献:

1、https://crossoverjie.top/2018/07/29/java-senior/ThreadPool/

2、

 

 

你可能感兴趣的:(#,Java,编程#线程池)