自定义线程池,自定义拒绝策略

自定义线程池

package org.jd.data.netty.big.window.chat.frame.ui.controller.center;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
/**
 * 设计模式: 单例模式
 * 自定义线程池: 实现业务需求:
 * 可以获取线程池内部细节,对排查程序故障有很大的好处
 */
@Slf4j
public final class SSOCustomerThreadPoolExecutor extends ThreadPoolExecutor {
 
    private static final int corePoolSize = 4;
    private static final long keepAliveTime = 10;
    private static final int maximumPoolSize = 10;
    private static final TimeUnit unit = TimeUnit.MILLISECONDS;  // 微秒
    private static final BlockingQueue workQueue = new LinkedBlockingQueue<>(10); // 队列容量
    private static final ThreadFactory threadFactory = new SSOCustomerThreadFactory();
 
    private static class SSOCustomerThreadPoolExecutorHandler {
        //static int maximumPoolSize = Runtime.getRuntime().availableProcessors();
        private static SSOCustomerThreadPoolExecutor newInstance = new SSOCustomerThreadPoolExecutor(maximumPoolSize * 2, threadFactory);
    }
 
    public static SSOCustomerThreadPoolExecutor newInstance() {
        return SSOCustomerThreadPoolExecutor.SSOCustomerThreadPoolExecutorHandler.newInstance;
    }
 
 
    private SSOCustomerThreadPoolExecutor(int maximumPoolSize, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory,new SSORejectedExecutionHandler());
    }
 
    @Override
    protected void beforeExecute(Thread task, Runnable r) {
        Runtime runtime = Runtime.getRuntime();
        int cupNum = runtime.availableProcessors();// 获取可以的CUP数量
        long freeMemory = runtime.freeMemory(); // 空闲内存 kb;
        long maxMemory = runtime.maxMemory();
        long totalMemory = runtime.totalMemory();
        System.out.println("current name: " + task.getName() + " | beforeExecute 可以的CPU数量: " + cupNum + " | 空闲内存: " + freeMemory + " | 最大内存: " + maxMemory + "  | 总内存: " + totalMemory);
    }
 
    @Override
    protected void afterExecute(Runnable task, Throwable t) {
        System.out.println("afterExecute Thread name : " + task.getClass().getSimpleName()+ " | current thread status :" + Thread.currentThread().getState()
                + " current thread id : " + Thread.currentThread().getId() + " | afterExecute poolSize : "
                + this.getPoolSize() + " | threadPool task num : "
                + this.getTaskCount() + " | finished task num: "
                + this.getCompletedTaskCount() + " | not finished task num: " + (this.getTaskCount() - this.getCompletedTaskCount()));
    }

 
}

自定义线程池饱和策略处理器:

package org.jd.data.netty.big.window.chat.frame.ui.controller.center;
 
import cn.hutool.json.JSONUtil;
import javafx.concurrent.Worker;
import org.jd.data.netty.big.window.chat.entity.SSOUser;
import org.jd.data.netty.big.window.chat.frame.ui.task.WorkerTask;
 
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
 
/**
 * 自定义线程池饱和时处理策略
 */
public class SSORejectedExecutionHandler implements RejectedExecutionHandler {
    final Map tempMap = new ConcurrentHashMap<>();
 
    /**
     * 具体实现方法,一般上线后,会把多余的线程任务,保存到日志或写库,这里模拟尝试几种处理
     *
     * @param r   进入该处的任务一定是被丢弃的
     * @param executor
     */
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        WorkerTask worker = (WorkerTask) r;
 
        // 模拟写日志
        System.err.println(worker.getId() + " 被丢弃! 此时消息为: "+ JSONUtil.toJsonStr(worker));
        tempMap.put(worker.getId(), r); // 被丢弃的任务加到tempMap中去
        // 重新放入队列里执行
        try {
            System.out.println("重新放入队列前的队列大小为: "+executor.getQueue().size());
            executor.getQueue().put(r);
            System.out.println("重新放入队列后的队列大小为: "+executor.getQueue().size());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
 
    }
}

你可能感兴趣的:(自定义线程池,自定义拒绝策略)