当前位置: 首页 > 面试题库 >

结合使用InheritableThreadLocal和ThreadPoolExecutor或不重用线程的ThreadPoolExecutor

潘驰
2023-03-14
问题内容

我正在尝试同时使用InheritableThreadLocalThreadPoolExecutor

由于ThreadPoolExecutor每个池(毕竟是一个池)都将线程重用,这意味着InheritableThreadLocal无法正常工作,因此出现了故障。现在这个问题对我来说似乎很明显,但要追踪它尤为困难。

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

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

问题在于,由于为ThreadPoolExecutor线程池重用了其线程,因此,该线程将
InheritableThreadLocal选择在该池中运行的原始值,而不是将Runnable发送到的顶级进程中的值ThreadPoolExecutor

  • 有什么方法可以强制工作池中的工作池ThreadPoolExecutor使用在InheritableThreadLocal创建Runnable的进程的上下文中使用的值,而不是在重用线程池的上下文中使用该值?

  • 或者,是否有任何实现在ThreadPoolExecutor每次启动新的Runnable时创建一个新线程?就我的目的而言,我只关心将同时运行的线程数控制到固定大小。

  • 人们对我有什么其他解决方案或建议,可以完成上述工作?

(虽然我意识到我可以通过将数据库连接从类到类再传递到子线程再到子线程来解决问题,就像某种社区自行车一样,但我想避免这种情况。)

关于StackOverflow,InheritableThreadLocal和线程池,还有一个先前的问题也可以解决此问题。但是,解决该问题的方法似乎是InheritableThreadLocal的用例很差,我认为这不适用于我的情况。

感谢您的任何想法。


问题答案:

为什么不使用ThreadPoolExecutor保护共享资源,而不是使用java.util.concurrent.Semaphore?您创建的子任务将在其自己的线程中运行完成,但仅在从信号量获得许可后才能完成,当然,完成后释放许可。



 类似资料:
  • 我读到有一个线程池,这个池注定要减少创建新线程的成本(至少我这样理解下面的短语): 当您向执行程序发送任务时,它会尝试使用一个池线程来执行此任务,以避免线程的持续生成。[Java7并发Cookbook] 但是,我知道我们没有办法在Java重启线程。 问题:ThreadPoolExecutor如何避免创建新线程?

  • 本文向大家介绍ThreadPoolExecutor线程池的使用方法,包括了ThreadPoolExecutor线程池的使用方法的使用技巧和注意事项,需要的朋友参考一下 ThreadPoolExecutor ThreadPoolExecutor线程池,java提供开发框架,管理线程的创建、销毁、优化、监控等。 有4种不同的任务队列: 1.ArrayBlockingQueue:基于数组结构的任务队列。

  • 本文向大家介绍Java ThreadPoolExecutor 线程池的使用介绍,包括了Java ThreadPoolExecutor 线程池的使用介绍的使用技巧和注意事项,需要的朋友参考一下 Executors Executors 是一个Java中的工具类. 提供工厂方法来创建不同类型的线程池. 从上图中也可以看出, Executors的创建线程池的方法, 创建出来的线程池都实现了 Executo

  • 如果正在运行的线程少于corePoolSize线程,则执行器宁愿添加一个新线程,而不是排队。2)如果corePoolSize或更多线程正在运行,则执行器更喜欢将请求排队,而不是添加新线程。 如果请求无法排队,将创建一个新线程,除非该线程将超过maximumPoolSize,在这种情况下,任务将被拒绝。 第一种情况是可以的,但我想要的是,当核心线程被利用时,任务不需要排队(即使在有界队列的情况下,比

  • 以下是Sun创建线程的简单规则: 如果线程数小于corePoolSize,请创建新线程以运行新任务 为什么在队列已满时创建非核心线程?我不明白他们为什么这样做。为什么不在队列为空时创建非核心线程?

  • 根据我的理解,ThreadpoolExecitor有两个主要的数据结构(工人,workQueue)用于管理tasks.worker(Set)有线程,这些线程将一直运行到执行器关闭,workerQueue将所有任务保留到执行器。但是根据代码,我没有看到所有任务都被添加到workQ中ueue.task仅在第1361行添加到队列中,不会在每种情况下都执行。