Correct Implementation of Java Future multithreading

纵饮孤独 提交于 2019-12-18 09:08:41

问题


In my servlet I am hitting several URL's to check their status and returning the response to user.

Hitting multipe requests takes lot of time: need threads and timouts. But i need my threads to geturn response : using Future for that reason.

My code outline:

ExecutorService executor = Executors.newFixedThreadPool(10);
Future<statusModel> future;

for (Map.Entry<String, String> url : urls.entrySet())
{
    try
    {
        future = executor.submit(new CallableRequestStatus(url.getValue()));
        status = (statusModel) future.get(5, TimeUnit.SECONDS);
        results.add(status);
    }
    catch (InterruptedException | ExecutionException | TimeoutException e) 
    {
        System.out.println("Error<checkServers>: Timeout OR "+e.getMessage());  
    }
}
executor.shutdownNow();

All the results from my callable class is coming in status object which I later add to an arraylist. My problem here is that my approach is blocking me from running all 10 threads at same time. I have to wait 5 secs for getting my status object and then move to next URL.

I am thinking my approach is faulty. I tried looking online but I couldnt find any example with custom objects and Arraylist involved.

Can anyone help me correct my fault. Thanks in advance

Finally Updated my code (thanks to Sotirios Delimanolis and Kevin):

ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<statusModel>> futures = new ArrayList<Future<statusModel>>();

for (Map.Entry<String, String> url : urls.entrySet())
{
    Future<statusModel> future = executor.submit(new CallableRequestStatus(url.getValue())); 
    futures.add(future);
}

ArrayList<statusModel> results = new ArrayList<statusModel>();
statusModel status;

int i=0;

for (Map.Entry<String, String> url : urls.entrySet())
{           
    try 
        {
            status = (statusModel) futures.get(i).get(500, TimeUnit.MILLISECONDS);
            // do some stuff with status and

            if(status.getStatusCode()/100 == 2)
                results.add(status);
        }
    catch (InterruptedException | ExecutionException | TimeoutException e) 
        {
            System.out.println("Error<checkServers>: Timeout OR "+e.getMessage());  
        }   
i++;
}

executor.shutdownNow();
System.out.println("Shutdown: "+executor.isShutdown());

Hope its helpful for someone :)


回答1:


You need to submit everything upfront, then wait separately. As below, exception handling removed for clarity:

ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<statusModel>> futures = new ArrayList<>();

for (Map.Entry<String, String> url : urls.entrySet())
{
    futures.add(executor.submit(new CallableRequestStatus(url.getValue())));
}
for (Future<statusModel> f : futures) {
    results.add((statusModel) f.get(5, TimeUnit.SECONDS));
}


来源:https://stackoverflow.com/questions/18316941/correct-implementation-of-java-future-multithreading

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!