Trt Trt
Trt Trt

Reputation: 5532

Do I need to call join() when stopping a Thread in Java?

I have these 5 simple thread that run a while loop:

flasherThread = new Thread(new Runnable() {
    @Override
    public void run() {
        while(running.get()) {
            // do network stuff         
        }
    }
});

running is declared as private final AtomicBoolean running;.

I have this method:

public void stopFlasherThread() {
    running.set(false);
}

My question is by setting the flag to false that stops the thread immediately ? Or do I need to call flasherThread.join() to make sure that the thread has stopped ?

The main issue is that I have 4-5 of these at a time.

So I have a loop such as:

for (int i = 0; i < 5; i++) {
    ThreadArrayList.get(i).stopFlasherThread();
    ThreadArrayList.get(i).join()  // should I do this ?
}

Any help would be great! Thanks

Upvotes: 1

Views: 1452

Answers (1)

Sebastian D&#39;Agostino
Sebastian D&#39;Agostino

Reputation: 1675

According to the official documentation on join:

The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,

t.join();

causes the current thread to pause execution until t's thread terminates.

So, no... or not necessarily, only if you need the result of the work of that thread to do something. The join will not stop / interrupt the thread, it will wait for it to finish its work. The stopFlasherThread will make the loop stop.

I would advise you to follow a different approach on using threads on Java using ExecutorService. For example:

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<AtomicInteger> futureResult = executor.submit(new Callable<AtomicInteger>() {
    @Override
    public AtomicInteger call() {
        // Here I return a random integer, but you can do your proper calculation
        AtomicInteger atomicInteger = 
            new AtomicInteger(ThreadLocalRandom.current().nextInt());
        System.out.println(Thread.currentThread().getName() + " " + atomicInteger);
        return atomicInteger;
    }
});

// Thread returns result, but continues to execute as it is a single thread pool
try {
    System.out.println(Thread.currentThread().getName() + " " + futureResult.get());
} catch (InterruptedException e) {
    // Handle exception properly
    e.printStackTrace();
} catch (ExecutionException e) {
    // Handle exception properly
    e.printStackTrace();
}

// Stop all threads
executor.shutdownNow();

There I define an inline class that extends the Callable interface and implement the call method to perform a task in another thread. This returns the result of the computation in the variable futureResult which is a Future. Since executor is a thread pool, it continues to be available to take tasks even though our task here has already been resolved. To finish the whole thread pool loop you can do a executor.shutdownNow().

Upvotes: 1

Related Questions