【问题标题】:Using ThreadPoolExecutor and connection pool without random blocking method call使用 ThreadPoolExecutor 和连接池没有随机阻塞方法调用
【发布时间】:2016-02-24 16:14:24
【问题描述】:

我已经使用 StackOverFlow 很长时间了,总是能找到现有的答案,但这次我找不到任何关于我正在尝试做什么的信息。

使用 java,我有一个由大约 10 个不同任务组成的进程,这些任务使用纯 jdbc(这里没有 ejb/jpa)从数据库中收集不同的数据。每个任务(可调用)实际上可以并发运行,并负责获取连接,这就是我们正在做的事情。但是我们随机遇到连接池问题(通过 jndi 访问),有时我们会因为连接池没有任何可用连接而被阻止。

为了解决这个问题,我认为我们可以改变获取连接的方式,而不是让每个可调用的打开和关闭连接(遵循要执行的任务数和要在 ThreadPoolExecutor 中使用的线程数),我想创建某种专用于该进程的本地连接池,以便我们确定以后不会阻塞(最终如果我们无法获取所有请求的连接,我们将调整线程数以适应启动至少 1)

我的同事同意这个想法,但令我惊讶的是,我在网络上找不到任何类似的方法或讨论(可能我没有使用正确的关键字)。

我想知道你对这个想法的看法,无论你是否已经尝试过类似的东西,或者我是否遗漏了一些重要的东西。

提前,谢谢。

【问题讨论】:

  • 10 个任务同时运行是否普遍?如果是,你真的需要他们吗?难道不能只限制线程池中并发运行的线程数,确保不会从连接池中获取所有数据库连接吗?我的意思是,如果你有 10 个可用连接,但你的线程池中的最大线程数是 3,你知道在最坏的情况下你仍然有 7 个连接。
  • 如果每个任务都在每个自己的线程中,为什么需要每个任务池?只需使用连接启动任务并始终使用相同的连接。
  • @ThiagoPorciúncula 在起源处,所有进程都在单个线程上的单个方法中,这需要很长时间,第一次优化(不是我的)为此添加了多线程,因此只有最长的请求将在这里受到限制,但他们错过了现在已修复的其他细节,但我认为这仍然不正确。使用来自服务器池的所有连接本身不是问题,这里重要的是确保不同的线程正确结束(这样我们就可以确保连接在此之后可用)。
  • @JPMoresmau :我不确定我们是否可以在多线程上下文中安全地共享单个连接(即使我们只在我的情况下进行选择操作)我会对此进行一些研究
  • 我的意思是每个线程使用一个连接,当然线程不应该共享连接。获取连接,为每个可以获取的连接打开一个线程,然后开始工作。

标签: java connection-pooling nonblocking threadpoolexecutor


【解决方案1】:

您没有提到使用哪个连接池。如果不是HikariCP 并且您可以切换,我推荐它。

【讨论】:

  • 确实,但恕我直言,我倾向于更喜欢可移植代码,而不是依赖于我无法完全控制的服务器端的任何特定实现。您的想法可能可行,但我会看看 hikariCP,但您没有解释使用它有什么好处
  • 选择经过良好测试且成熟的库或工具比编写自己的库或工具更明智,因为主要考虑到“并发性很难做到正确”。您可以根据需要调整很少的参数来启动和运行,它在流行的池中是最“便携”的。链接有更多信息,也可以在 wiki 中阅读。
【解决方案2】:

HikariCP 最后似乎很有趣,我得进一步检查一下。但这与问题没有直接关系:)

【讨论】:

    【解决方案3】:

    只是一点经验的回报,我的想法正在奏效,但需要注意的是,我无法摆脱从可运行对象到我的实现的沮丧,我可以在我的 before() 期间执行 .setConnection()执行器服务。并且所有任务都必须使用 execute() 方法交给执行程序,否则可运行对象会自动包装在 FutureTask 中,而无法访问内部可运行对象。也许你们中的一个人知道正确地做到这一点?

    【讨论】:

    • 最后添加一个,我仍然需要做一个小改动来正确管理当服务器太长而无法响应时打开太晚的连接,至少我们会有一个可用的连接,这足以启动执行器服务,通过将其限制为连接数(最坏的情况下只有一个)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    相关资源
    最近更新 更多