记录一次排查线程死锁问题

应用偶现某个页面加载不出来,但是又不崩溃的情况,排查原因记录

public T executeSync(@Nullable Queue queue, @NonNull IDbOptProxy<T> opt) {
        if (checkExecuteOrigin(queue)) {
            return opt.executeOpt();
        }
        final DbOptCallback<T> callback = new DbOptCallback<>();
        DbOptLogger logger = new DbOptLogger();
        assert queue != null;
        Rx2QueueUtil.backgroundTaskOnMain(queue, () -> {
            callback.onResult(opt.executeOpt());
            logger.tick();
            return 0;
        }, null).subscribe();
        while (!callback.optDone()) {
            SystemClock.sleep(1);
        }
        logger.end();
        CLog.d(TAG, "[sync] %s", logger.getLog());
        return callback.getResult();
    }

private static <T> Observable<T> backgroundTaskOnMain(@NonNull Scheduler scheduler, @NonNull Callable<T> callable,
        @Nullable LifeEndOwner owner) {
        Observable<T> observable = Observable.fromCallable(callable)
            .subscribeOn(scheduler)
            .observeOn(AndroidSchedulers.mainThread());
        if (owner != null) {
            observable = observable.compose(owner.bindToEnd2());
        }
        return observable;
    }

这段代码实现了一个将耗时的任务放到单独的后台线程执行,并在执行完成后回调到主线程的功能。executeSync方法接受一个线程名和一个opt参数,其中线程名用于指定后台线程的名称,opt参数是一个实现了OptCallback接口的回调对象,用于执行耗时任务并在执行完成后回调。

在executeSync方法内部,首先通过Rx2QueueUtil.getQueue方法获取一个线程名为queueName的线程,并将opt封装成一个Callable对象。然后,调用Rx2QueueUtil.backgroundTaskOnMain方法,将该Callable对象在queueName线程上执行,并将执行结果发布到主线程上的Observable对象中。最后,通过Observable的阻塞方法blockingFirst获取执行结果,并将结果返回给executeSync方法的调用者。

如果在多线程环境下,多个线程同时调用executeSync方法,可能会出现死锁问题。例如,如果线程A调用executeSync方法,将任务放到线程B执行,并在等待执行结果时被阻塞;同时,线程B在执行任务前也调用了executeSync方法,将任务放到线程A执行,并在等待执行结果时被阻塞,那么就会发生死锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值