阻塞检查机制

阻塞检查机制

  如何感知线程是否发生阻塞,在很多应用场景下这都是值得我们去思考的问题。如果线程因为各种原因长时间发生阻塞,则会影响系统执行效率,降低系统tps。
  为了感知线程阻塞问题,我们可以建立一套线程阻塞自感知机制,对线程状态进行监控,当检测到当前任务执行线程的任务执行时间过长时,自动触发告警,提醒开发人员系统存在线程阻塞,进行问题定位和排查。

如何实现线程阻塞检查机制

1. 设计思路

  设置一个block checker,业务线程执行任务前,在block checker处注册阻塞监控,设置阻塞时间阈值,业务线程执行完任务后,通知block checker任务完成,监控解除。
  若超过阻塞时间阈值但block checker仍未收到业务线程的任务完成通知,则触发阻塞告警。

2. 实现方案

  将block checker设置为定时任务线程池。业务线程执行任务前,往block checker中添加delay time为阻塞时间阈值的定时任务,同时传入回调方法作为阻塞触发时的action。
  业务线程执行完任务后,需解除定时任务,否则到达阻塞时间阈值后会触发阻塞回调。

3. 实现代码

/**
 * 阻塞监控触发future对象
 *
 * @author ian
 * @date 2022年9月1日 下午5:50:51
 */
public class BlockCheckFuture {
    private final ScheduledFuture<?> scheduledFuture;

    public BlockCheckFuture(ScheduledFuture<?> scheduledFuture) {
        this.scheduledFuture = scheduledFuture;
    }

    /**
     * 结束阻塞监控
     */
    public void endCheck() {
        if (!scheduledFuture.isCancelled()) {
            scheduledFuture.cancel(false);
        }
    }
}

/**
 * 线程阻塞检查器
 *
 * @author ian
 * @date 2022年9月1日 下午5:46:38
 */
public class BlockCheckerUtil {
    private static final ScheduledExecutorService scheduledExecutorService;
    private static final int CORE_SIZE = 1;

    static {
        scheduledExecutorService = new ScheduledThreadPoolExecutor(CORE_SIZE, r -> {
            Thread t = new Thread(r);

            // 设置为daemon,低优先级,减少cpu占用
            t.setDaemon(true);
            t.setName("blockCheckerThread");
            return t;
        });
    }

    /**
     * 阻塞监控
     *
     * @param time 时间
     * @param timeUnit 时间单位
     * @param thresholdCallback 阻塞回调
     * @return block check future,for ending checking monitor
     */
    public static BlockCheckFuture blockCheck(long time, TimeUnit timeUnit, ThresholdHitCallback thresholdCallback) {
        Thread current = Thread.currentThread();
        ScheduledFuture<?> future = scheduledExecutorService.schedule(
                () -> thresholdCallback.callback(current), time, timeUnit);
        return new BlockCheckFuture(future);
    }
}

4. 使用示例

public static void main(String[] args) {
        BlockCheckFuture future = null;
        try{
            // 阻塞感知
            future = BlockCheckerUtil.blockCheck(2000, TimeUnit.MILLISECONDS, new ThresholdHitCallback() {
                @Override
                public void callback(Thread observedThread) {
                    Log.error("thread is blocking !");
                }
            });
            
            // do your business ...
            
        } finally {
            future.endCheck();     
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值