有序线程池(可根据订单号hash到同一个线程处理,适用于消息消费)

package com.dingxy.database.util;

import com.google.common.hash.Hashing;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author: 
 * @since: 2024/12/17 下午3:45
 * @description:自定义有序线程池
 * @version: 1.0 , Copyright (c) 2023 by ZTE Co.
 */
public class OrderedThreadPoolExecutor {

    private final InnerTaskWorker[] taskWorkers;
    private final ThreadFactory threadFactory;
    public OrderedThreadPoolExecutor(int concurrency,ThreadFactory threadFactory){
        this.taskWorkers = new InnerTaskWorker[concurrency];
        this.threadFactory = threadFactory;
        this.init(concurrency);
    }

    private void init(int concurrency){
        this.initFillRunTasks(concurrency);
        this.addShutdownHook();
    }

    /**
     * 初始化填充并行任务
     * @param taskCount 任务数,即并发度
     */
    private void initFillRunTasks(int taskCount) {
        for (int i = 0; i < taskCount; i++) {
            this.taskWorkers[i] = new InnerTaskWorker(this.threadFactory);
        }
    }

    /**
     * 设置jvm退出的钩子,响应中断、释放资源
     * 1. 不再接受新任务
     * 2. 停止内部线程池
     */
    private void addShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread(() ->
                Arrays.asList(this.taskWorkers).forEach(InnerTaskWorker::stopWorker)));
    }

    /**
     * 根据提供的hashKey,执行有序的任务
     * @param hashKey 分区标识
     * @param task    任务
     */
    public void executeOrdered(int hashKey, Runnable task) {
        int i = hashKey % taskWorkers.length;
        this.taskWorkers[i].addWorker(task);
    }


    private static final class InnerTaskWorker{
        private final  SynchronousQueue<Runnable> sq;
        private final  AtomicInteger threadState;
        private final ThreadFactory threadFactory;
        private volatile  Thread command;

        private InnerTaskWorker(ThreadFactory threadFactory){
           this.sq = new SynchronousQueue<>();
           this.threadState = new AtomicInteger(1);
           this.threadFactory = threadFactory ;
           this.init();
        }

        private void  init(){
            this.startWorker();
        }

        private Boolean isRunning(){
            return  this.threadState.get() == InnerThreadState.RUNNING;
        }

        private Boolean isTerminated(){
            return  this.threadState.get() == InnerThreadState.TERMINATED;
        }

        private void startWorker(){
            this.command = threadFactory.newThread(()->{
                while (this.isRunning()){
                    try {
                        sq.take().run();
                    } catch (InterruptedException e) {
                        if (this.isTerminated()){
                            throw new RuntimeException(e);
                        }
                    }catch (RuntimeException t){
                        this.handleWorkerException();
                        throw  t;
                    }
                }
            });
            this.command.start();
        }
        /**
         * 处理任务异常时,继续有工作线程执行任务
         */
        private void handleWorkerException() {
            this.threadState.set(InnerThreadState.EXCEPTED);
            // 通过cas方式来启动新线程
            // 这个判断不是脱裤子放屁,因为threadState.set()与startWorker()并不是原子操作
            if (this.threadState.compareAndSet(InnerThreadState.EXCEPTED, InnerThreadState.RUNNING)) {
                this.startWorker();
            }
        }

        private void addWorker(Runnable r){
            try {
                sq.put(r);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        private void stopWorker(){
            this.threadState.set(InnerThreadState.TERMINATED);
            this.command.interrupt();

            try {
                this.command.join();
            } catch (InterruptedException e) {
                System.out.println("abcdf");
            }
        }

    }

    public static void main(String[] args) {

        OrderedThreadPoolExecutor orderedExecutor = new OrderedThreadPoolExecutor(64,new CustomThreadFactory("order-"));

        Runnable task = () -> {
            if (new Random().nextBoolean()) {
                try {
                    System.out.println("hhahah");
                    Thread.sleep(20L);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                // 模拟偶尔业务代码抛出异常情况
                if (new Random().nextBoolean()) {
                    throw new RuntimeException("Test exception");
                }
            }
        };

        StringBuilder log = new StringBuilder();

        for (int i = 0; i < 1000; i++) {
            try {
                String orderId = "o_" + (100_000_000 + i);
                int hash = Math.abs(Hashing.murmur3_32().hashBytes(orderId.getBytes()).asInt());
                orderedExecutor.executeOrdered(hash, task);
            } catch (Exception ignore) {
                // 忽略模拟的业务代码异常
            }
        }

        InnerTaskWorker[] tws = orderedExecutor.taskWorkers;
        for (int i = 0; i < tws.length; i++) {
            log.append(tws[i].command.getName())
                    .append(" ==> ")
                    .append(tws[i].command.getState())
                    .append("\n");
        }

        System.out.println(log);
    }

    /* Started by AICoder, pid:6a35441173024a02956093915a9e1bca */

    public static final  class CustomThreadFactory implements ThreadFactory {

        private final String namePrefix;
        private final AtomicInteger threadId = new AtomicInteger(0);

        public CustomThreadFactory(String namePrefix) {
            this.namePrefix = namePrefix;
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, namePrefix + "-thread-" + threadId.getAndIncrement());
            return t;
        }
    }
    /* Ended by AICoder, pid:6a35441173024a02956093915a9e1bca */

    /**
     * 内部线程状态码
     */
    private static final class InnerThreadState {
        /**
         * 正常运行
         */
        private static final int RUNNING = 1;
        /**
         * 异常停止
         */
        private static final int EXCEPTED = 2;
        /**
         * 正常结束
         */
        private static final int TERMINATED = 3;
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值