为什么我的Executor服务每次接近完成时都会卡住?



简单地说,我有一个列表userid,它可以有从10k到100k的任何数字的大小,这些是user_id,我的核心逻辑是,对于每个user_id,我调用两个不同的rest api端点并获得这些有效载荷,然后在有效载荷

之间进行验证操作我使用了执行器服务,以以下方式进行更快的处理,我将记录分成批次并预定义了100个线程,以便1个线程可以处理(int)(userid .size()/100)用户

public void execute(List < String > userIds) {
int numberOfThreads = 100;
int WINDOW = (int) Math.floor(userIds.size() / numberOfThreads);

int st = 0;
int end = WINDOW;

for (; st < userIds.size();) {
int realStart = st;
int realEnd = end;
executor.execute(
() - > {
verify(realStart, realEnd, userIds) // this method has logic to verify users for the given start and end indexes from the userIds list
}
)

st = end + 1;
if (end + WINDOW >= userIds.size()) {
end = userIds.size() - 1;
} else {
end = st + WINDOW;
} // code to update the indexes realStart and realEnd for next 'n' batches
}
executor.shutDown();
try {
System.out.println("Done");
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
System.out.println("Done on a rope");
} catch (Exception e) {
e.printStackTrace();
}
}

让我们说10k记录当它接近完成时,代码卡住了,这让我认为如果有几个线程被卡住在exectuorService,如果是这样,我如何工作,或者有任何明显的缺陷在这里?任何帮助都是感激的:)

假设有100个线程,您的系统可以处理它。

则问题可以在verify()方法内。比方说,你有1万名用户->每个线程一次处理100个用户。

  1. verify()方法的逻辑无法处理
  2. users Id'suserIds列表中不是唯一的,并且几个线程正在尝试并发地处理相同的userId,并且可能在与该用户Id相关的一些资源上死锁。
  3. 线程相互阻塞的另一个问题,但再次-这取决于您的应用程序逻辑

注意:executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);只告诉executor是否完成了它的处理,它不会在时间过去后强制它终止。根据Oracle,正确的结束方式是:

executor.shutdown();
try {
if (!executor.awaitTermination(800, TimeUnit.MILLISECONDS)) {
executor.shutdownNow();
} 
} catch (InterruptedException e) {
executor.shutdownNow();
}

另一个注意事项:您可以使用while (st<userIds.size())代替半空的for (; st < userIds.size();)

相关内容

  • 没有找到相关文章

最新更新