我想用两个InheritableThreadLocal和一个ThreadPoolExecutor.
这会因为ThreadPoolExecutor重用每个池的线程而崩溃(毕竟它是一个池),这意味着InheritableThreadLocal它不能按预期工作.现在这个问题对我来说显而易见,但追踪却特别狡猾.
我使用InheritableThreadLocal这样几个顶级进程中的每一个都有自己的数据库连接以及它产生的任何子进程.我不只是使用一个共享连接池,因为在提交到数据库和/或准备大量反复使用的PreparedStatements之前,每个顶级进程都会对其连接进行大量的多步骤工作.
我使用ThreadPoolExecutor这些顶级进程之间的共享,因为某些行为需要进行门控.尽管我可能有4个顶级进程在运行,但我一次只能有一个进程写入数据库(或者系统需要访问其他一些共享资源).因此,我将让顶级进程创建Runnable并将其发送到共享ThreadPoolExecutor,以确保在整个系统中同时运行不超过一个(或两个或三个).
问题在于,因为ThreadPoolExecutor重用了池中的线程,所以它将获取在该池中 InheritableThreadLocal运行的原始值,而不是将Runnable发送到的顶级进程中的值ThreadPoolExecutor.
有没有办法强制工作池ThreadPoolExecutor使用InheritableThreadLocal创建Runnable的进程上下文中的值而不是在重用线程池的上下文中?
或者,是否有任何实现在ThreadPoolExecutor每次启动新的Runnable时创建一个新线程?出于我的目的,我只关心将同时运行的线程的数量设置为固定大小.
有没有其他解决方案或建议人们让我完成我上面描述的内容?
(虽然我意识到我可以通过将类数据库连接从类传递到子线程到子线程来解决问题,就像某种社区自行车一样,我想避免这种情况.)
还有一个关于StackOverflow,InheritableThreadLocal和线程池的问题也解决了这个问题.但是,该问题的解决方案似乎是它对于InheritableThreadLocal来说是一个糟糕的用例,我不认为这适用于我的情况.
谢谢你的任何想法.
我正在使用ThreadPoolExecutorJava来管理大量正在运行的线程.我创建了自己的简单,ThreadFactory所以我可以给线程更好的名字.
问题是,首次创建线程池时,名称在线程中设置,并且不与线程池实际运行的任务相关联.我理解这一点......我的Runnables和Callables - 尽管它们有名字 - 实际上是从ThreadPoolExecutor运行线程中提取的一个层次.
StackOverflow上还有一些关于为ThreadPoolExecutor线程池创建名称的问题.(请参阅如何为可调用线程命名?以及如何在Java中命名线程池的线程.)
我想知道的是:有没有人有一个很好的解决方案来保持线程池线程的名称与它实际运行的Runnable同步?
即如果我打电话Thread.getCurrentThread().getName(),我想它不会重返顶级线程池的名称,而是可赎回/名称Runnable的该线程当前正在运行.
由于这主要是为了调试和日志记录的目的,我试图避免一个解决方案,涉及我将新代码放入可能提交给ThreadPoolExecutor的每个Runnable中 - 我只是将一些代码放入ThreadFactory或包装ThreadPoolExecutor本身,以便在一个地方完成更改.如果不存在这样的解决方案,我可能不会打扰,因为它不是关键任务.
开始编辑为了澄清,我知道我可以把一个Thread.currentThread().setName( "my runnable name" );作为每个Runnable的run方法的第一行,但我试图避免这样做.我在这里是一个完美主义者,我意识到这一点,所以如果人们想对这个问题发表评论并告诉我,我不会被冒犯.结束编辑
我想,我的另一个问题是人们是否认为做这样的事情是个坏主意.我是否应该像这样更新线程池名称?
谢谢你的任何建议!