2013-04-13 72 views
1

例如,如何在本地同步兩張地圖?

class Test{ 
    static Map a = new ... 
    static Map b = new ... 

    public void process(){ 

     ... 
     a.put(...); 
     b.put(...); 
    } 
} 

我一定要鎖定這樣的:

synchronized(a){ 
    a.put(); 
} 

synchronized(b){ 
    b.put(b); 
} 

這似乎是尷尬。任何其他正確的方法來做到這一點?謝謝。

+1

這確實取決於你想要的併發保證。 –

+0

你可以使用'Lock'來解決這個問題,這可能是一種矯枉過正或同步的方法。 –

回答

2

不,您需要兩個操作在一個​​塊中,否則另一個線程可能會在兩個映射之間看到不一致。

一種可能的選擇是使用​​方法,或者您可以使用其他私人對象或其中一個地圖作爲監視器。下面是同步的方法,例如:

static Map a = new ... 
    static Map b = new ... 

    public synchronized void process(){ 

     ... 
     a.put(...); 
     b.put(...); 
    } 
} 
0

你確實需要一個​​塊內同時運行操作。值得注意的是,在你的例子中,你已經靜態定義了地圖,而process()方法是一個實例方法。同步方法將意味着對該實例的調用將被同步,但是對2個不同實例的調用將不會(因爲在將方法應用到方法時使用的鎖實際上是this)。您可以將process()方法設爲靜態,也可以使用synchronized(Test.class) {}塊來確保沒有賽車發生。

您還需要注意如何將地圖展示給客戶端 - 如果您將它們作爲屬性提供,那麼我可能會用Collections.unmodifiableMap()包裝它們以確保沒有其他東西可以去,當你不在尋找的時候將它們擰緊 - 但是這並不能完全保護客戶有一個「奇怪」的時間,因爲他們仍然會看到變化發生在潛在的不安全的方式。因此,我想也可能宣佈類型作爲一個ConcurrentHashMap來讓事情變得更安全(雖然還存在一些諸如共享線程之間的Iterator危險作業)

1

您可以使用專用的對象像

Object mapLock = new Object(); 

要同步。

或者您也可以a牢記,即使你需要b的訪問,你需要在a Sync同步。

同步於this通常不是一個好主意。我的意思是這是一個壞習慣,如果不是這個,但是你做的其他應用程序,最終可能導致性能不佳或不明顯的死鎖。

Avoid synchronized(this) in Java?

您也可以考慮使用ReadWriteLock中的併發包。