2010-03-23 86 views
4

我想多線程的應用程序,但是我使用的一個庫不支持多線程(我不知道什麼是正確的單詞?同步?)。如果一個庫不是多線程,該怎麼辦?

我有什麼選擇?

據我所知,在java中的線程和進程(Runtime.exec)之間沒有任何東西(在jvm中沒有抽象類似於獨立的「java進程」)。

你會如何處理?

編輯

感謝所有的答案,再次,一層間接的伎倆。

+2

您正在查找的單詞是「線程安全的」。 – 2010-03-23 13:38:56

+0

@Stephen C:謝謝。我無法想起它。 – LB40 2010-03-23 13:54:17

回答

11

您可以確保所討論的庫一次只能從一個線程使用。如果它包含可實例化的類,則有一種可能性是將它們保存在thread local storage中。

或者你可以在它周圍建立一個線程安全的wrapper

這些方法也可以組合,例如,你可以將這個庫封裝到一個類中(在這種情況下,它將是一個Facade),它本身不是線程安全的,但是一次只能從一個線程訪問其實例。

更新:爲@Wim指出,如果庫管理全局狀態,你必須一個線程安全的包裝,以確保改變線程之間可見。

+0

第一個確實意味着第二個。您需要內存屏障來確保緩存一致性(每個線程應該在庫中的任何全局狀態下具有相同的視圖) – 2010-03-23 13:43:07

+0

@Wim非常好的一點,謝謝。 – 2010-03-23 13:51:08

6

我會創建一個Facade,而不是直接使用該庫。門面應該將連接/呼叫同步到圖書館。

喜歡的東西:

External Call External Call External Call 
     |    |    | 
     ----------------------------------    
        Wrapper 
         | 
        Library 

更新:

的立面可能是錯誤的設計模式,因爲它是用來隱藏功能。 包裝應該作爲設計模式

+3

Facade是一個稍微不同的問題的設計模式 - 它應該是一個包裝或適配器。 – 2010-03-23 13:30:51

+0

Facade應該隱藏功能,在這種情況下其他類。也許你是對的,它也可能是一個包裝。 – 2010-03-23 13:33:40

2

我會寫一個瘦包裝,所有的相關方法是同步的,並且我然後在我的代碼中使用,而不是直接使用圖書館的類和方法隨處可見。我首先要評估一下,圖書館的哪些部分實際上是必要的。

有時替代方案可以是爲每個線程使用庫對象的單獨實例。但是在這種情況下,這些實例不能在線程間共享。

+0

作爲同步方法的替代方法,您可以使用鎖定(例如ReentrantReadWriteLock)來減少瓶頸,前提是您瞭解庫管理器的行爲並可以決定何時使用ReadLock和WriteLock。 – Sylar 2010-03-23 13:39:09

+1

@塞巴斯蒂安:如果你對圖書館有足夠的瞭解,可以完成。也許應該指出,如果這導致多個鎖對象,那麼顯然你也必須確保避免死鎖。 – 2010-03-23 13:46:26

3

很大程度上取決於庫的大小以及它的用途。首先要做的是評估你可能實際存在併發問題的地方。只是因爲您在多個線程中使用庫並不意味着它不能用於多個線程。在API中查找具體說明「這不是線程安全」的項目,如果您將使用API​​的那部分,則需要自己同步它。最簡單的解決方案是創建一個包裝類來同步所有的方法。例如,查看集合實用程序的源代碼(如Collections.synchronizedList等)。

+1

請注意,儘管設計時考慮到線程安全的庫並不很明確地在其API文檔中明確聲明「這不是線程安全的」:-( – 2010-03-23 13:48:04

2

看看Collections API中的相似問題是如何解決的。所有集合默認都不是線程安全的。

但是當你需要一個線程安全的集合,你只需用

Collections.synchronizedCollection(unsafeCollection) 

實現從用戶隱藏得到它,它不是API的一部分。你可以用同樣的方法。

相關問題