2012-12-09 47 views
0

請不要把下面的問題看作是重複的問題..!關於同步的不同方法

我開發了一個讓多線程按順序依次運行的類。這個類的claimAccess函數和release Access函數之間的所有應用程序代碼一次只能在一個線程中執行。所有其他線程將在隊列中等待,直到前一個線程完成。現在請告知可以同樣的事情由像執行人,循環障礙或倒計時鎖也有一些其他的方式來實現.. !!請建議如何能夠通過其他途徑建立

import java.util.ArrayList; 
import java.util.List; 

public class AccessGate { 
    protected boolean shouldWait = false; 
    protected final List waitThreadQueue = new ArrayList(); 

    /** 
    * For a thread to determine if it should wait. It it is, the thread will 
    * wait until notified. 
    * 
    */ 
    public void claimAccess() { 
     final Thread thread = getWaitThread(); 
     if (thread != null) { 
      // let the thread wait untill notified 
      synchronized (thread) { 
       try { 
        thread.wait(); 
       } catch (InterruptedException exp) { 
       } 
      } 
     } 
    } 

    /** 
    * For a thread to determine if it should wait. It it is, the thread will be 
    * put into the waitThreadQueue to wait. 
    * 
    */ 
    private synchronized Thread getWaitThread() { 
     Thread thread = null; 
     if (shouldWait || !waitThreadQueue.isEmpty()) { 
      thread = Thread.currentThread(); 
      waitThreadQueue.add(thread); 
     } 
     shouldWait = true; 
     return thread; 
    } 

    /** 
    * Release the thread in the first position of the waitThreadQueue. 
    * 
    */ 
    public synchronized void releaseAccess() { 
     if (waitThreadQueue.isEmpty()) { 
      shouldWait = false; 
     } else { 
      shouldWait = true; 
      // give the claimAccess function a little time to complete 
      try { 
       Thread.sleep(10); 
      } catch (InterruptedException exp) { 
      } 

      // release the waiting thread 
      final Thread thread = (Thread) waitThreadQueue.remove(0); 
      synchronized (thread) { 
       thread.notifyAll(); 
      } 
     } 
    } 
} 
+0

排序的任務很重要嗎? –

+0

@NarendraPathai是啊必須維護訂單 – user1881169

+0

'Executors.newSingleThreadExecutor()'呢? –

回答

2

這是由ExecutorService

手段

Executors.singleThreadExecutor()將一次執行一項任務,並將按順序執行。

創建一個使用單個worker線程的 無界隊列操作Executor。 (然而,注意,如果此單個線程關閉之前執行期間終止 由於故障,一個新的將 如果需要的話,執行後續任務取而代之。)任務是 保證執行依次,且無超過一個任務將在任何給定時間處於活動狀態 。

+0

你可以請發佈更新的代碼,因爲我已經做了這些將有助於更多的理解,謝謝 – user1881169

+1

@ user1881169你應該先自己嘗試,然後如果有問題,你總是可以再問一次。 :)我們在這裏幫助。 –

+0

謝謝,但我無法實現,如果你可以請發佈更新的代碼,這將是一個很大的幫助,在此先感謝 – user1881169

2

是的,有更簡單的方法來做到這一點。非常簡單的是隻使用一個顯示器,無需等待,睡覺,或任何其他的惡作劇:

// somewhere visible 
public final Object accessGate = new Object(); 

// in your application code 
synchronized (accessGate) { 
    // this block will be executed only in one thread at one time 
} 

Java的內置顯示器提供非常需要的語義。唯一的問題是線程獲得鎖的順序不能保證;這取決於底層操作系統如何處理鎖的排序(信號量或互斥鎖或其他)。操作系統可以很好地保證你所需要的行爲,但這通常不是可移植的。

如果您需要訂購的便攜式保證,您有幾個選擇。最明顯的是ReentrantLock公平設置爲true:

// somewhere visible 
public final Lock accessGate = new ReentrantLock(true); 

// in your application code 
accessGate.lock(); 
try { 
    // this block will be executed only in one thread at one time 
} 
finally { 
    accessGate.unlock(); 
} 

另一個是Semaphore與單個許可證和公平設置爲true:

// somewhere visible 
public final Semaphore accessGate = new Semaphore(1, true); 

// in your application code 
accessGate.acquire(); 
try { 
    // this block will be executed only in one thread at one time 
} 
finally { 
    accessGate.release(); 
} 

這兩個具有非常相似的行爲。

+0

@ TomAnderson ..感謝了很多,你提出的兩種方法真的很有幫助,你可以請發佈完整的更新代碼,因爲我已經做了......這將有助於更多地瞭解 – user1881169

+0

你能請發佈完整的代碼,謝謝 – user1881169

+0

上面的代碼不會保證訂購!但問題提到訂單將保留 –