2009-12-05 37 views
8

我有兩個數組,我需要跨線程同步對它們的訪問。我將把它們放在同步塊中。問題是,我只能通過其中一個來「同步」一次。java同步塊的超過1個對象?

如何確保對兩個陣列的訪問都是同步的? 我把它們放在課堂上並創建它的一個對象嗎? 或者我只在同步塊中訪問另一個數組,並且這需要同步對它的訪問嗎?

感謝,

+0

把他們放在一個新班級可能有助於澄清你想要做什麼,所以我會建議。但是,這根本不影響線程安全性。我喜歡使用顯式鎖定的答案(如下)。 – 2009-12-05 13:47:54

回答

20

不管你做什麼做到這一點:

synchronized (array1) { 
    synchronized (array2) { 
    // do stuff 
    } 
} 

這可能導致deadlock除非你非常小心。如果你採用這種方法,你必須確保你對物體有一個不變的部分順序 - 谷歌「餐飲哲學家」討論這些陷阱。

基本上你所要做的是創造,如果你想訪問要麼數組,你將使用,然後利用它來進行所有數組訪問一個鎖定對象。它粗粒,但安全。如果你需要,你要使用Java 5+等併發公用事業ReadWriteLock更細粒度的方法,但是這將是更加複雜的實現,而且容易出錯

public static class TwoArrays { 
    private int[] array1 = ... 
    private int[] array2 = ... 
    private final Object LOCK = new Object(); 

    public void doUpdate() { 
    synchronized (LOCK) { 
     ... 
    } 
    } 
} 

:你可以這樣來做。

+1

然後,你可以使'doUpdate'同步,而不是增加'LOCK'對象的複雜性。 – skaffman 2009-12-05 08:26:31

+3

其實不是,最好不要暴露你的鎖,這是你在做鎖的時候所做的。 – cletus 2009-12-05 08:30:10

+0

這會產生一個問題 - 如果在同一對象上存在另一個同步,則使用嵌套同步塊可能會導致死鎖。但是隻有上面的代碼存在纔會發生嗎?如果沒有數組的監視器,則線程無法獲取array2的監視器。如果它具有array1的監視器,則其他線程不能擁有array2的監視器。我的推理有沒有漏洞? – Bozho 2009-12-05 08:52:48

11

到Java 5之前,我已經寫了這樣的事情:

// pre Java 5 code: 
Object lock = new Object(); 
// ... 
synchronized(lock) { 
    // do something that requires synchronized access 
} 

但自從Java 5中,我會使用類從java.util.concurrent.locks(個人而言,我不覺得這是更復雜或錯誤易發):

// Java 5 Code Using Locks 
Lock lock = // ... 
lock.lock(); 
try { 
    // do something that requires synchronized access 
} 
finally { 
    lock.unlock(); 
} 

如果你需要讀寫鎖,我這裏是使用讀寫鎖從Java 5中實現:

private ReadWriteLock rwl = new ReentrantReadWriteLock(); 
private Lock rLock = rwl.readLock(); 
private Lock wLock = rwl.writeLock(); 

private List<String> data = new ArrayList<String>(); 

public String getData(int index) { 
    rLock.lock(); 
    try { 
     return data.get(index); 
    } finally { 
     rLock.unlock(); 
    } 
} 

public void addData(int index, String element) { 
    wLock.lock(); 
    try { 
     data.add(index, element); 
    } finally { 
     wLock.unlock(); 
    } 
} 

當然,適應它來滿足您的需求。