2010-11-30 53 views
2

我有一個方法,比如method1(),需要一段時間才能運行。在執行期間,如果有另一個對method1()的調用,它應該被忽略。我大致有這樣的東西有沒有一種替代/更好的方法在java中完成這個簡單的邏輯?

boolean mFlag = false; 

    void method1() 
    { 
     if(!mFlag) 
     { 
      mFlag=true; 

      // do Stuff 

      mFlag=false; 
     } 
    } 

這是有效的。但我想知道是否有更好的方法來做到這一點,最好不涉及任何標誌。

+1

這很好。這是通常的做法。 – 2010-11-30 20:07:55

+1

您是否試圖解決一次執行同一方法的多個線程問題,或者該方法(也許間接)調用自身的問題? – 2010-11-30 20:10:10

回答

6

是的,你確實應該利用的java.util.concurrent.locks你舉的例子不是很嚴格正確的東西,那布爾需要揮發。

ReentrantLock lock = new ReentrantLock(); 

    void method1() 
    { 
     if(lock.tryLock()) 
     { 
      try { 
      if (!(lock.getHoldCount() > 1)) { 
       //do Some Stuff 
      } 
      } finally { 
      lock.unlock(); 
      } 
     } 
    } 

被編輯爲處理跳過在您的評論中指出的再進入執行。不幸的是,使用內置庫並不是一個很好的方法,因爲它有點奇怪,但我仍然認爲使用內置庫是一個更好的選擇。

1

您是否試圖防止來自同一線程或同時訪問多個線程的重新進入?

假設多線程訪問,light方法是使用java.util.concurrent.atomic。沒有必要像鎖一樣「沉重」(只要沒有進一步的要求)。

假設從相同的方法沒有折返:

private final AtomicBoolean inMethod = new AtomicBoolean(); 

void method1() { 
    if (inMethod.compareAndSet(true, false)) { // Alternatively getAndSet 
     try { 
      // do Stuff 
     } finally { 
      inMethod.set(false); // Need to cover exception case! 
     } 
    } 
} 

如果你想允許同一線程內折返,那麼它得到足夠的亂用鎖:

private final AtomicReference<Thread> inMethod = new AtomicReference<Thread>(); 

void method1() { 
    final Thread current = Thread.currentThread(); 
    final Thread old = inMethod.get(); 
    if (
     old == current || // We already have it. 
     inMethod.compareAndSet(null, current) // Acquired it. 
    ) { 
     try { 
      // do Stuff 
     } finally { 
      inMethod.set(old); // Could optimise for no change. 
     } 
    } 
} 

可以使用爲此執行成語。

相關問題