Java中的多锁单解锁?

时间:2015-12-15 18:01:40

标签: java multithreading locking

我正在实现我的RunnableFuture版本,并且需要在run()方法结束时雾化状态更改。特定的州字段列表无关紧要。 Runnable可以通过例外或正常结束。因此,它可以访问try块的尾部,也可以不访问。我也可以访问catch块,然后finally阻止。

所有这3个地方都应该原子地改变,但是我不能看到" interblock"锁定结构。因此,我使用getHoldCount()来决定是否致电lock()

public void run() {

      Runnable runnable;

      lock.lock();
      try{
         runnable = this.runnable;
         done = false;
         running = true;
         result = null;
      }
      finally {
         lock.unlock();
      }

      try {
         if( !cancel ) {
            runnable.run();
         }

         if( lock.getHoldCount()==0 ) lock.lock();
         exception = null;
         result = finalResult;

      }
      catch (Exception e) {

         if( lock.getHoldCount()==0 ) lock.lock();

         exception = e;
         result = null;

      }
      finally {
         if( lock.getHoldCount()==0 ) lock.lock();
         done = true;
         running = false;

         lock.unlock();
      }

   }

这是否正确,有没有更好的方法呢?

2 个答案:

答案 0 :(得分:1)

为什么不链接try-finally语句:

try {
    lock.lock();
    // Do something ...
} finally {
    try {
        // Do more ...
    } finally {
        try {
            // Do more ...
        } finally {
            lock.unlock();
        }

}

答案 1 :(得分:0)

任何时候逻辑变得足够复杂,我不得不问,"这会起作用吗?"我把它分解成子程序:

public void run() {
    setup();
    exception ex = doRun();
    report(ex);
}

private void setup() {
    lock.lock();
    try{
        done = false;
        running = true;
        result = null;
    } finally {
        lock.unlock();
    }
}

private Exception doRun() {
    try {
        if( !cancel ) {
            this.runnable.run();
        }
    } catch (Exception e) {
        return e;
    }
    return null;
}

private void report(Exception ex) {
    lock.lock();
    try {
        done = true;
        running = false;
        if (ex != null) {
            exception = ex;
            result = null;
        } else {
            exception = null;
            result = finalResult;
        }
    } finally {
        lock.unlock();
    }
}