2017-01-26 55 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或者实现你的版本(其实它就像一个阵列添加链表和数组元素的列表,其避免了巨大的锁锁)