At the end of the execution, I have to collect all the results from threads and use Stream<Object> to retrieve search results. So, threads are not totally executed independently because a common data structure is needed to collect all thread results after threads execution. To address that, I have used Callable<Object> interface. The problem with this approach is, it waits to all thread results sequentially. Some threads which start later can be finished the execution earlier compared to some other older threads. Since results are collected sequentially, already finished threads have to wait until get their chance.