We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
首先感谢您使用 DynamicTp,如果对项目有任何疑问需要解答,请按照下述模板提问,建议使用 Markdown 语法。
问题来源参见 4.2.2节
public Object doGet() { ExecutorService threadPool1 = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(100)); CompletableFuture cf1 = CompletableFuture.supplyAsync(() -> { //do sth return CompletableFuture.supplyAsync(() -> { System.out.println("child"); return "child"; }, threadPool1).join();//子任务 }, threadPool1); return cf1.join(); }
如上代码块所示,doGet方法第三行通过supplyAsync向threadPool1请求线程,并且内部子任务又向threadPool1请求线程。threadPool1大小为10,当同一时刻有10个请求到达,则threadPool1被打满,子任务请求线程时进入阻塞队列排队,但是父任务的完成又依赖于子任务,这时由于子任务得不到线程,父任务无法完成。主线程执行cf1.join()进入阻塞状态,并且永远无法恢复。
文章中也提到了解决方案:为了修复该问题,需要将父任务与子任务做线程池隔离,两个任务请求不同的线程池,避免循环依赖导致的阻塞。
尝试扩展了下 ExecutorAware,在execute方法里面,将提交任务的线程所对应的线程池名称记录下来并绑定到任务上,然后在beforeExecute中,获取当前实际执行的线程池的名称,和任务中绑定的名称做对比,如果相等,则认为发生了【线程池循环引用】。
ExecutorAware
execute
beforeExecute
这样的方式,解决父子任务【AA】场景是没有问题的,但是如果是【ABA】这样的方式就无能为力了(如下),想知道这个问题有办法解决吗?
private void test() { DtpRegistry.getDtpExecutor("dtp1").submit(() -> { System.out.println("--------------------"); System.out.println("in dtp1"); System.out.println("--------------------"); DtpRegistry.getDtpExecutor("dtp2").submit(() -> { System.out.println("--------------------"); System.out.println("in dtp2"); System.out.println("--------------------"); DtpRegistry.getDtpExecutor("dtp1").submit(() -> { System.out.println("--------------------"); System.out.println("in dtp1"); System.out.println("--------------------"); }); }); }); }
The text was updated successfully, but these errors were encountered:
挺好的想法,我觉得可以用ttl做线程池场景下的上下文传递,任务提交后将当前线程名称保存到ThreadLocal中,是个list,执行前可以从ThreadLocal获取值来判断当前线程池名称是否包含,这样就可以通过包含关系来判断是否有嵌套引用吧。
Sorry, something went wrong.
forkjoinpool
这种问题,不仅仅存在单个接口内部,接口之间也可能存在线程池的循环嵌套。这个估计需要维护一个线程池引用树来判断线程池之间的嵌套关系
No branches or pull requests
首先感谢您使用 DynamicTp,如果对项目有任何疑问需要解答,请按照下述模板提问,建议使用 Markdown 语法。
使用方面
问题背景
问题来源参见 4.2.2节
如上代码块所示,doGet方法第三行通过supplyAsync向threadPool1请求线程,并且内部子任务又向threadPool1请求线程。threadPool1大小为10,当同一时刻有10个请求到达,则threadPool1被打满,子任务请求线程时进入阻塞队列排队,但是父任务的完成又依赖于子任务,这时由于子任务得不到线程,父任务无法完成。主线程执行cf1.join()进入阻塞状态,并且永远无法恢复。
文章中也提到了解决方案:为了修复该问题,需要将父任务与子任务做线程池隔离,两个任务请求不同的线程池,避免循环依赖导致的阻塞。
具体问题:除了线程池隔离这样的人为约定,有没有办法通过代码实现【线程池循环引用】的自动监控?
尝试扩展了下
ExecutorAware
,在execute
方法里面,将提交任务的线程所对应的线程池名称记录下来并绑定到任务上,然后在beforeExecute
中,获取当前实际执行的线程池的名称,和任务中绑定的名称做对比,如果相等,则认为发生了【线程池循环引用】。这样的方式,解决父子任务【AA】场景是没有问题的,但是如果是【ABA】这样的方式就无能为力了(如下),想知道这个问题有办法解决吗?
The text was updated successfully, but these errors were encountered: