Thread.join() equivalent in executor

You shouldn't use executor like this if you want to wait for tasks to finish. What if you don't want/can't shutdown your thread pool executor? This is a more recommended way:

    ExecutorService exec = Executors.newFixedThreadPool(3);
    Collection<Future<?>> tasks = new LinkedList<Future<?>>();

    Future<T> future = exec.submit(A);
    tasks.add(future);
    future = exec.submit(B);
    tasks.add(future);
    future = exec.submit(C);
    tasks.add(future);

    // wait for tasks completion
    for (Future<?> currTask : tasks) {
            try {
                currTask.get();
            } catch (Throwable thrown) {
                Logger.error(thrown, "Error while waiting for thread completion");
            }
        }

We can use below code to join the thread.

 executor.execute(new YouThread());

    try{     
         executor.shutdown();
         while (!executor.awaitTermination(24L, TimeUnit.HOURS)) {
             System.out.println("Not yet. Still waiting for termination");
         }                
    }catch(InterruptedException e){
        e.printStackTrace();
    }

executor.shutdown();
while (!executor.awaitTermination(24L, TimeUnit.HOURS)) {
    System.out.println("Not yet. Still waiting for termination");
}

Use shutdown() + awaitTermination() combination.

EDIT:

Based on the comment of @Lital

List<Callable<Object>> calls = new ArrayList<Callable<Object>>();
calls.add(Executors.callable(new IncrementalRunable(1, aHolder)));
calls.add(Executors.callable(new IncrementalRunable(2, aHolder)));
calls.add(Executors.callable(new IncrementalRunable(3, aHolder)));

List<Future<Object>> futures = executor.invokeAll(calls);

NOTE: invokeAll() will not return until all the tasks are completed (either by failing or completing successful execution).