2017-01-26 57 views
3

我想知道如果我需要實現我自己的連接池,什麼是高級算法?實現自定義連接池?

我在谷歌上瀏覽了一些解決方案(下面的鏈接),但所有這些看起來都不可擴展。當我說可擴展 我主要關注getConnection()/borrowConnection()方法,我需要確保多個線程同時調用此方法在 同時,他們沒有得到相同的連接,並且等待也是最小的。以下所有解決方案均使用同步方法/塊方法 ,因爲它在電子商務線程必須等待的應用程序中根本無法擴展。

  1. https://codereview.stackexchange.com/questions/40005/connection-pool-implementation
  2. http://www.javaworld.com/article/2076690/java-concurrency/build-your-own-objectpool-in-java-to-boost-app-speed.html
  3. https://sridharrao85.wordpress.com/2011/07/20/sample-connection-pool-implementation/
  4. http://www.javamadesoeasy.com/2015/12/connection-pooling-in-java-with-example.html

礦山解決方案: -基本上我的做法側重於如何減少在粒度級別的併發性,而不是在數據結構持有 連接池。因此,我將保持兩個列表(arralylist)

  1. ConnectionsNotInUse
  2. ConnectionInUse

ConnectionsNotInUse將持有的所有連接(包裹在自定義連接類)在啓動池。現在,如果一個線程要求連接,一旦它獲得成功,它將從ConnectionsNotInUse中移除並將其放入ConnectionsInUse中。

在每個自定義連接類中,都會有方法getConnection()方法,該方法將使用Semaphore.tryAcquire(),該方法獲取一個鎖,如果有一個鎖可用並立即返回,則值爲true。這將是一個許可證的信號量。所以如果線程沒有獲得連接,它將循環返回列表中的另一個連接。

如果最後線程沒有得到任何連接,它將創建另一個連接,如果最大允許限制允許,否則它將等待連接被釋放。 一旦連接被釋放,它會通知等待連接的線程

對方法提出的任何意見/建議建議?

+0

你在這裏暗示連接速度太快,以至於同步過於昂貴 - 那麼你有什麼樣的網絡(它將使用該連接)比線程系統更快在同一個CPU上進行同步?換句話說,你確定它會成爲瓶頸嗎? – john16384

+0

@ john16384這將是一個肯定的瓶頸。考慮電子商務網站,其中有數百萬的請求試圖同時獲取連接。通過方法/塊同步,每個請求必須以順序方式運行。 – emilly

+0

您的站點可能需要一次提供一百萬個請求,但是沒有一次可處理一百萬個線程的Java VM。大多數可擴展的設置將處理像最多1000個線程(通常較低)並排隊其餘。然後通過多個實例的負載均衡來實現進一步的縮放。 – john16384

回答

0

據我理解你的描述:

原來實行的連接池就像是隻有一個入口,只有一個人(線程)的房間是允許獲得你所擔心的人將在入口處排隊並影響您的應用的可擴展性。所以你決定有多個入口(免費清單)。但你似乎沒有指定他們應該嘗試的入口,我假定你讓他們嘗試第一個。如果第一個不可用,他們會嘗試下一個入口。

所以如果我的理解是正確的,他們選擇的入門政策是表現的核心。如果他們都嘗試第一,然後第二,它將與原始實施沒有什麼區別。

我能想到的快速和無同步方式是散列人的身份。如果導致高考是不是免費的任何更多,將有兩種方式:

  • 查找下一個
    • 哈希再次
    • 下一個位置,等
  • 創造新

因此,從比喻。 我描述的是什麼樣的一個HashMap的實現,你可以嘗試在兩個方面:

  • 與HashMap的
  • 更換您的列表中使用一個單一的地圖使用和自由連接混合,在這種情況下,你可能會避免巨型鎖定,但您需要使用ConcurrentHashMap或實現您的版本。

一些注意事項:

  • 如果您使用的是由不同的線程共享,以保持兩個列表,你仍然需要對他們的巨大的鎖,否則會崩潰的。
  • 您將增加連接計數以便與最大允許連接進行比較,這也需要同步。

幾點建議:

  • 使用原子整數計數器
  • 使用的ConcurrentHashMap或者實現你的版本(其實它就像一個陣列添加鏈表和數組元素的列表,其避免了巨大的鎖鎖)