简单地说,我有一个列表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个用户。
verify()
方法的逻辑无法处理users Id's
在userIds
列表中不是唯一的,并且几个线程正在尝试并发地处理相同的userId,并且可能在与该用户Id相关的一些资源上死锁。- 线程相互阻塞的另一个问题,但再次-这取决于您的应用程序逻辑
注意: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();)