被线程池中的锁忽悠了,原来是这样用的。

一直用并发库,但ThreadPoolExecutor的源码没有详细看过,主要想看看Doug Lea大神的设计思路。

说一下在一处代码上的疑问,主要是Worker这个类,内部有一处代码

private final ReentrantLock runLock = new ReentrantLock();

有2处方法会用到

第一个是runTask方法

   private void runTask(Runnable task) {
            final ReentrantLock runLock = this.runLock;
            runLock.lock();
            try {
                /*
                 * Ensure that unless pool is stopping, this thread
                 * does not have its interrupt set. This requires a
                 * double-check of state in case the interrupt was
                 * cleared concurrently with a shutdownNow -- if so,
                 * the interrupt is re-enabled.
                 */
                if (runState < STOP &&
                    Thread.interrupted() &&
                    runState >= STOP)
                    thread.interrupt();
                /*
                 * Track execution state to ensure that afterExecute
                 * is called only if task completed or threw
                 * exception. Otherwise, the caught runtime exception
                 * will have been thrown by afterExecute itself, in
                 * which case we don't want to call it again.
                 */
                boolean ran = false;
                beforeExecute(thread, task);
                try {
                    task.run();
                    ran = true;
                    afterExecute(task, null);
                    ++completedTasks;
                } catch (RuntimeException ex) {
                    if (!ran)
                        afterExecute(task, ex);
                    throw ex;
                }
            } finally {
                runLock.unlock();
            }
        }

因为这个Worker不是单例的,也就是说每次都新建一个Worker类,而且内部的锁也是NEW的实例。这样加不加锁没有区别。

让我不思其解,直到看到

另一处为interruptIfIdle方法,才明白原来是这样用的。

      void interruptIfIdle() {
            final ReentrantLock runLock = this.runLock;
            if (runLock.tryLock()) { 
                try {
                      if (thread != Thread.currentThread())
                           thread.interrupt();
                } finally {
                    runLock.unlock();
                }
            }
        }

这里的runLock.tryLock为如果拿到锁,说明当前Worker线程没有处于RUNNING状态,可进行线程中断。

如果没有拿到锁,说明Worker正在执行任务。

这个问题主要是阅读代码的时候不够仔细, 还有就是经验主义想当然的认为锁是在经验范围内的用法。

 

转载于:https://my.oschina.net/jaedong/blog/371584

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值