sách gpt4 ai đã đi

java - 如何避免使用递归调用使 executorservice 拥塞/停滞/死锁

In lại 作者:行者123 更新时间:2023-11-29 07:23:40 34 4
mua khóa gpt4 Nike

ExecutorService 中的所有线程都忙于等待执行程序服务队列中卡住的任务。

Mã ví dụ:

ExecutorService es=Executors.newFixedThreadPool(8);
Set<><>>> outerSet=new HashSet<>();
for(int i=0;i<8;i++){
outerSet.add(es.submit(new Callable<>>() {

@Ghi đè
public Set call() throws Exception {
Thread.sleep(10000); //to simulate work
Set<>> innerSet=new HashSet<>();
for(int j=0;j<8;j++) {
int k=j;
innerSet.add(es.submit(new Callable() {
@Ghi đè
public String call() throws Exception {
return "number "+k+" in inner loop";
}

}));
}
Set out=new HashSet<>();
while(!innerSet.isEmpty()) { //we are stuck at this loop because all the
for(Future f:innerSet) { //callable in innerSet are stuckin the queue
if(f.isDone()) { //of es and can't start since all the threads
out.add(f.get()); //in es are busy waiting for them to finish
}
}
}
return out;
}
}));
}

除了为每一层创建更多线程池或使用大小不固定的线程池之外,还有什么方法可以避免这种情况?

一个实际的例子是,如果一些可调用对象被提交给 ForkJoinPool.commonPool(),然后这些任务使用的对象也在它们的方法之一中提交给 commonPool。

1 Câu trả lời

您应该使用 ForkJoinPool。它就是为这种情况而制作的。

虽然您的解决方案在等待其子任务完成时永久阻塞线程,但窃取 ForkJoinPool 的工作可以在 join() 中执行工作。这使得它对于这些类型的情况非常有效,在这些情况下,您可能正在运行数量可变的小型(并且通常是递归的)任务。对于常规线程池,您需要扩大它的大小,以确保您不会用完线程。

sử dụng CompletableFuture,您需要自己处理更多的实际计划/安排,如果您决定更改内容,调整起来会更加复杂。使用 FJP,您唯一需要调整的是池中的线程数量,使用 CF,您需要考虑 sau đóthenAsync 也是如此。

关于java - 如何避免使用递归调用使 executorservice 拥塞/停滞/死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58812542/

34 4 0
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com