2015-09-22 37 views
5

我有一個名爲processOutbox的方法。我希望它是線程安全的。我不希望另一個線程在一個線程處於此狀態時調用此方法。我已通過以下方式實施它。我做對了嗎?我的實施有沒有漏洞?如果有任何問題,請諮詢我如何解決問題。如何確保線程安全在以下方面?

this.start(); 
    outboxLock.lock(); 
    timer = new Timer(); 
    try{ 
    timer.scheduleAtFixedRate(new TimerTask() { 
      public void run() { 
       processOutbox(); 
      } 
     }, 0, period); 
    } finally{ 
     outboxLock.unlock(); 
    } 
+4

您只鎖定了排程。執行仍然不是線程安全的。 – Fildor

+0

那我該怎麼做呢?請指教。 – mayooran

+0

我會建議在類級靜態變量上同步它。 –

回答

5

如果你想使你的方法processOutbox,你應該使用關鍵字​​:

public class YourClass{ 
    public synchronized void processOutbox(){ 
     //do all you want 
    } 
} 

更多信息在:https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

如果你的代碼中呼籲YourClass的實例例如myInstance,所有對processOutbox()的調用都將是線程安全的,因爲它們將在實例級鎖定。

例如:

YourClass myInstance = new YourClass(); 
Thread thread1 = new Thread(){ 
    public void run(){ 
     myInstance.processOutbox(); 
    } 
    } 
Thread thread2 = new Thread(){ 
    public void run(){ 
     myInstance.processOutbox(); 
    } 
    } 
thread1.start(); 
thread2.start(); 

這裏thead2會等到線程1結束通話,以 「processOutbox」

但例如:

YourClass myInstance = new YourClass(); 
YourClass myInstance2= new YourClass(); 
Thread thread1 = new Thread(){ 
    @Override 
    public void run(){ 
     myInstance.processOutbox(); 
    } 
}; 
Thread thread2 = new Thread(){ 
    @Override 
    public void run(){ 
     myInstance2.processOutbox(); 
    } 
} 
thread1.start(); 
thread2.start(); 

thead2將等待,因爲他們在不同的實例上調用該方法。

有人專門詢問了有關使用ReentrantLock的問題 - 所以我將這個響應添加到這一個中,因爲這個是正確的。

public class YourClass { 
    private Lock outboxLock = new ReentrantLock(); 
    public void processOutbox() { 
     outboxLock.lock() 
     try { 
      // do stuff 
     } finally { 
      outboxLock.unlock() 
     } 
    } 
} 

我提到這一點,特別是因爲你還可以做的事情,在那裏你把其他線程離開鎖而不會使玩家使用的tryLock到塊。

public class YourClass { 
    private Lock outboxLock = new ReentrantLock(); 
    public void processOutbox() { 
     if(outboxLock.tryLock()) { 
      try { 
       // do stuff 
      } finally { 
       outboxLock.unlock() 
      } 
     } 
    } 
} 
+0

**我不希望另一個線程在一個線程處於調用該方法時調用此方法。** –

+0

Java API:「當一個線程正在爲一個對象執行一個同步方法時,所有其他調用同步方法的線程對象塊(掛起執行),直到第一個線程完成對象。「 –

+0

如何使用可重入鎖實現相同?請諮詢悟國:) – mayooran

相關問題