Нужно ли вызывать join () при остановке потока в Java? - PullRequest
0 голосов
/ 25 июня 2018

У меня есть 5 простых потоков, которые запускают цикл while:

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

running объявлено как private final AtomicBoolean running;.

У меня есть этот метод:

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

Мой вопрос, установив флаг в false, который немедленно останавливает поток? Или мне нужно вызвать flasherThread.join(), чтобы убедиться, что поток остановлен?

Основная проблема заключается в том, что у меня есть 4-5 таких одновременно.

Итак, у меня есть цикл, такой как:

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

Любая помощь будет отличной! Спасибо

1 Ответ

0 голосов
/ 25 июня 2018

Согласно официальной документации о присоединении :

Метод объединения позволяет одному потоку ожидать завершения другого. Если t является объектом Thread, поток которого в данный момент выполняется,

t.join();

заставляет текущий поток приостанавливать выполнение до тех пор, пока поток t не завершится.

Так что нет ... или не обязательно, только если вам нужен результат работы этого потока, чтобы что-то сделать. join не будет останавливать / прерывать поток, он будет ждать, пока он завершит свою работу. stopFlasherThread остановит цикл.

Я бы посоветовал вам придерживаться другого подхода к использованию потоков в Java с использованием ExecutorService . Например:

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();

Там я определяю встроенный класс, который расширяет интерфейс Callable и реализует метод call для выполнения задачи в другом потоке. Это возвращает результат вычисления в переменной futureResult, которая является Future . Поскольку executor является пулом потоков, он по-прежнему доступен для выполнения задач, хотя наша задача здесь уже решена. Чтобы завершить весь цикл пула потоков, вы можете сделать executor.shutdownNow().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...