在ThreadPoolExecutor中使用InheritableThreadLocal - 或者 - 不重用线程的ThreadPoolExecutor [英] Using InheritableThreadLocal with ThreadPoolExecutor -- or -- a ThreadPoolExecutor that doesn't reuse threads

查看:198
本文介绍了在ThreadPoolExecutor中使用InheritableThreadLocal - 或者 - 不重用线程的ThreadPoolExecutor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 InheritableThreadLocal ThreadPoolExecutor

这打破了,因为的ThreadPoolExecutor 重用线程为每个池(它是一个池,毕竟),这意味着的InheritableThreadLocal 无法按预期工作。现在这个问题对我来说显而易见,但追踪是特别狡猾的。

This breaks down because ThreadPoolExecutor reuses threads for each pool (it is a pool, after all), meaning the InheritableThreadLocal doesn't work as expected. Now the problem seems obvious to me, but it was particularly snarly to track down.

我使用 InheritableThreadLocal 以便几个顶级进程中的每一个都有自己的数据库连接以及它产生的任何子进程。我不只是使用一个共享连接池,因为每个顶级进程在提交数据库和/或准备大量反复使用的PreparedStatements之前,会对其连接进行大量的多步骤工作。

I use InheritableThreadLocal so that each of several top-level processes has its own database connection for itself and any sub-processes it spawns. I don't just use one shared connection pool because each top-level process will do a lot of multi-step work with its connection before committing to the database and/or preparing a lot of PreparedStatements that are used over and over.

我在这些顶级进程之间使用共享 ThreadPoolExecutor ,因为某些行为需要进行门控。例如即使我可能有4个顶级进程在运行,但我一次只能有一个进程写入数据库(或者系统需要访问其他一些共享资源)。所以我将让顶级进程创建一个 Runnable 并将其发送到共享 ThreadPoolExecutor 以确保在整个系统中,不超过一个(或两个或三个)在整个系统中同时运行。

I use a shared ThreadPoolExecutor between these top-level processes because there are certain behaviors that need to be gated. e.g. Even though I might have 4 top-level processes running, I can only have any one process writing to the database at a time (or the system needs to gate on some other shared resource). So I'll have the top-level process create a Runnable and send it to the shared ThreadPoolExecutor to make sure that no more than one (or two or three as the case may be) are running at the same time across the entire system.

问题是因为的ThreadPoolExecutor 重用其线程池,在的InheritableThreadLocal 正在回升这是在池中运行,而不是价值的原始值是在顶级进程中将Runnable发送到 ThreadPoolExecutor

The problem is that because the ThreadPoolExecutor reuses its threads for the pools, the InheritableThreadLocal is picking up the original value that was run in that pool rather than the value that was in the top-level process which sent the Runnable to the ThreadPoolExecutor.


  • 有没有办法来强制工人池的ThreadPoolExecutor 来使用,这是在该的InheritableThreadLocal 值创建Runnable而不是在重用线程池的上下文中的进程的上下文?

  • Is there any way to force the worker pool in the ThreadPoolExecutor to use the InheritableThreadLocal value that was in the context of the process which created the Runnable rather than in the context of the reused thread pool?

或者,是否存在的任何实现ThreadPoolExecutor 创建一个新线程每次启动一个新的Runnable?出于我的目的,我只关心将同时运行的线程的数量设置为固定大小。

Alternatively, is there any implementation of ThreadPoolExecutor that creates a new thread each time it starts a new Runnable? For my purposes I only care about gating the number of simultaneously running threads to a fixed size.

是否有任何其他解决方案或建议供我完成我上面描述了什么?

Is there any other solution or suggestion people have for me to accomplish what I've described above?

(虽然我意识到我可以通过传递数据库连接来解决问题class to class to subthread like subthread就像某种社区自行车一样,我想避免这种情况。)

(While I realize I could solve the problem by passing around the database connection from class to class to subthread to subthread like some kind of community bicycle, I'd like to avoid this.)

StackOverflow上有一个上一个问题,InheritableThreadLocal和线程池,也解决了这个问题。但是,该问题的解决方案似乎是它对于InheritableThreadLocal来说是一个糟糕的用例,我不认为这适用于我的情况。

There is a previous question on StackOverflow, InheritableThreadLocal and thread pools, that addresses this issue as well. However, the solution to that problem seems to be that it's a poor use case for InheritableThreadLocal, which I do not think applies to my situation.

感谢您的任何想法。

推荐答案

代替使用的ThreadPoolExecutor保护共享资源的,为什么不使用 java.util.concurrent中。旗语?你创建的子任务将在他们自己的线程中运行完成,但只有在从信号量获得许可后才能完成,当然在完成时释放许可。

Instead of using a ThreadPoolExecutor to protect shared resources, why not use a java.util.concurrent.Semaphore? The sub tasks you create would run to completion in their own threads, but only after having acquired a permit from the semaphore, and of course releasing the permit when done.

这篇关于在ThreadPoolExecutor中使用InheritableThreadLocal - 或者 - 不重用线程的ThreadPoolExecutor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆