我基本上有一个字符串列表(大约20到60个字符串),我想发送一个帖子请求(并获取将采用json格式的结果,并将响应中的特定值附加到新列表中),每个列表中的项目。我想将ThreadPoolExecutor与特定数量的工作人员一起使用。
我尝试了几件事,但不幸的是我做不到。我可以一次执行一个请求,但这效率不高,而且需要很长时间。
我在python中有这段代码,该代码完全可以实现我想做的事情,但不幸的是我无法在Java中重现它。
#This function makes a single request using one string from the list
def getname(id):
url = "https://api-public-service.battledash.co/fortnite/cosmetics/search/id?q=" + id
with requests.session() as ss:
l = ss.get(url).json()
#we return a value from the response
return(l['readableName'])
def getnamelist(ids):
result = []
ids = deque(ids)
#Turning the list into a dict and back to list in order to remove duplicated items
ids = list(dict.fromkeys(ids))
#max workers is set to 10
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
#running the getname function which sends a single request and return a name from id
results = executor.map(getname,ids)
#appending all results into a list
for it in tuple(results):
result.append(it)
return(result)
答案 0 :(得分:0)
注意:由于您未指定Java版本,因此我的答案针对Java> = 8。
假设您具有以下线程安全的函数:public SomeHttpResponseType performGetRequest(String url)
:
public List<SomeHttpResponseType> performGetRequests(List<String> urls) {
return urls.stream().parallelStream()
.map(this::performGetRequest)
.collect(Collectors.toList())
}
这使用默认的ForkJoinPool。如果要指定自己的线程池,请尝试如下操作:
ForkJoinPool forkJoinPool = null;
try {
forkJoinPool = new ForkJoinPool(parallelism);
forkJoinPool.submit(() ->
urls.stream().parallelStream()
.map(this::performGetRequest)
.collect(Collectors.toList())
).get()
} catch(InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
if (forkJoinPool != null) {
forkJoinPool.shutdown(); //always remember to shutdown the pool
}
}
(https://www.codementor.io/nitinpuri/controlling-parallelism-of-java-8-collection-streams-umex0qbt1的适应版本)