我想用两个InheritableThreadLocal和一个ThreadPoolExecutor.
这会因为ThreadPoolExecutor重用每个池的线程而崩溃(毕竟它是一个池),这意味着InheritableThreadLocal它不能按预期工作.现在这个问题对我来说显而易见,但追踪却特别狡猾.
我使用InheritableThreadLocal这样几个顶级进程中的每一个都有自己的数据库连接以及它产生的任何子进程.我不只是使用一个共享连接池,因为在提交到数据库和/或准备大量反复使用的PreparedStatements之前,每个顶级进程都会对其连接进行大量的多步骤工作.
我使用ThreadPoolExecutor这些顶级进程之间的共享,因为某些行为需要进行门控.尽管我可能有4个顶级进程在运行,但我一次只能有一个进程写入数据库(或者系统需要访问其他一些共享资源).因此,我将让顶级进程创建Runnable并将其发送到共享ThreadPoolExecutor,以确保在整个系统中同时运行不超过一个(或两个或三个).
问题在于,因为ThreadPoolExecutor重用了池中的线程,所以它将获取在该池中 InheritableThreadLocal运行的原始值,而不是将Runnable发送到的顶级进程中的值ThreadPoolExecutor.
有没有办法强制工作池ThreadPoolExecutor使用InheritableThreadLocal创建Runnable的进程上下文中的值而不是在重用线程池的上下文中?
或者,是否有任何实现在ThreadPoolExecutor每次启动新的Runnable时创建一个新线程?出于我的目的,我只关心将同时运行的线程的数量设置为固定大小.
有没有其他解决方案或建议人们让我完成我上面描述的内容?
(虽然我意识到我可以通过将类数据库连接从类传递到子线程到子线程来解决问题,就像某种社区自行车一样,我想避免这种情况.)
还有一个关于StackOverflow,InheritableThreadLocal和线程池的问题也解决了这个问题.但是,该问题的解决方案似乎是它对于InheritableThreadLocal来说是一个糟糕的用例,我不认为这适用于我的情况.
谢谢你的任何想法.
我正在使用ExecutorService(ThreadPoolExecutor)来运行(和排队)很多任务.我试图编写一些尽可能优雅的关闭代码.
ExecutorService有两种关闭方式:
ExecutorService.shutdown()然后ExecutorService.awaitTermination(...).ExecutorService.shutdownNow().根据JavaDoc,shutdown命令:
Initiates an orderly shutdown in which previously submitted
tasks are executed, but no new tasks will be accepted.
Run Code Online (Sandbox Code Playgroud)
并且shutdownNow命令:
Attempts to stop all actively executing tasks, halts the
processing of waiting tasks, and returns a list of the tasks that were
awaiting execution.
Run Code Online (Sandbox Code Playgroud)
我想要这两个选项之间的东西.
我想调用一个命令:
a.完成当前活动的任务(如shutdown).
湾 停止等待任务的处理(如shutdownNow).
例如:假设我有一个包含3个线程的ThreadPoolExecutor.它目前在队列中有50个任务,前3个正在运行.我想允许完成这3个活动任务,但我不希望剩余的47个任务启动.
我相信我可以通过保持一个Future对象列表然后调用cancel所有这些来以这种方式关闭ExecutorService .但是由于任务是从多个线程提交给此ExecutorService的,因此没有一种干净的方法可以做到这一点.
我真的希望我错过一些明显的东西,或者有办法干净利落地做.
谢谢你的帮助.
我正在使用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方法的第一行,但我试图避免这样做.我在这里是一个完美主义者,我意识到这一点,所以如果人们想对这个问题发表评论并告诉我,我不会被冒犯.结束编辑
我想,我的另一个问题是人们是否认为做这样的事情是个坏主意.我是否应该像这样更新线程池名称?
谢谢你的任何建议!
我想看看是否有一个很好的模式,可以在不使用顶级线程的所有类和子线程的情况下共享上下文InheritableThreadLocal.
我有几个顶级进程,每个进程都在自己的线程中运行.这些顶级进程通常会产生临时子线程.
我希望每个顶级流程都拥有并管理自己的数据库连接.
我不希望绕过从类类数据库连接,并从线程的子线程(我的同事这个所谓的"社区自行车"模式).这些是大型顶级进程,这意味着可能会编辑数百个方法签名来传递此数据库连接.
现在我调用单例来获取数据库连接管理器.单例使用,InheritableThreadLocal以便每个顶级进程都有自己的版本.虽然我知道有些人对单身人士有问题,但这意味着DBConnector.getDBConnection(args)只要我需要正确管理的连接,我就可以说(换句话说).如果我能找到一个更好但仍然干净的解决方案,我不会依赖这种方法.
由于各种原因InheritableThreadLocal被证明是棘手的.(见这个问题.)
有没有人有一个建议来处理这种不需要或者InheritableThreadLocal遍布某个上下文对象的东西?
谢谢你的帮助!
更新:我设法解决了眼前的问题(请参阅相关问题),但我仍然希望了解其他可能的方法.下面的四十二个建议是好的,并且确实有效(谢谢!),但请参阅评论为什么它有问题.如果人们投票支持jtahlborn的答案并告诉我,我因为想要避免绕过我的数据库连接而迷恋,那么我会松懈,选择那个作为我的答案,并修改我的世界观.
我想知道Java中是否有一种方法可以使用两个锁对象进行同步。我的意思不是锁定任何一个对象,而是仅锁定两个对象。
例如,如果我有 4 个线程:
在上面的场景中,线程 A 和线程 D 将共享一个锁,但线程 B 和线程 C 将拥有自己的锁。即使它们与两个对象之一重叠,但只有在两个对象都重叠时才应用相同的锁。
所以我有一个由许多线程调用的方法,它将根据特定的数据库执行特定的活动类型。我有数据库和活动的标识符对象,并且我可以保证该操作将是线程安全的,只要它不是基于与另一个线程相同的数据库的相同活动。
我理想的代码看起来像这样:
public void doActivity(DatabaseIdentifier dbID, ActivityIdentifier actID) {
synchronized( dbID, actID ) { // <--- Not real Java
// Do an action that can be guaranteed thread-safe per unique
// combination of dbIT and …Run Code Online (Sandbox Code Playgroud)