Листинг 7.15 - LogService - Параллелизм Java на практике - Попытка добавить завершение ожидания с тайм-аутом - PullRequest
0 голосов
/ 09 ноября 2018

В листинге 7.15 «Параллелизма Java на практике» есть пример производителя / потребителя без ожидания завершения при остановке метода.

Основной поток в исходном коде не ожидает завершения потока журнала. Это может вызвать проблемы, особенно при входе в файл, и файл необходимо манипулировать после остановки. Исключение может быть сгенерировано, если потребитель все еще использует файл.

Работает ли следующий код, добавляя ожидание завершения с таймаутом для метода stop?

public class LogService {

private final BlockingQueue<String> queue;
private final LoggerThread loggerThread;
private final PrintWriter writer;
private final Object lock;
private boolean shutdown;
private boolean prepareShutdown;
private int reservations;

public LogService(Writer writer) {
    this.queue = new LinkedBlockingQueue<String>();
    this.loggerThread = new LoggerThread();
    this.writer = new PrintWriter(writer);
    this.lock = new Object();
}

public void start() {
    loggerThread.start();
}

public void stop(long timeout) throws InterruptedException {
    synchronized (lock) {
        prepareShutdown = true;
    }
    loggerThread.interrupt();
    try {
        loggerThread.join(timeout);
    } finally {
        synchronized (lock) {
            shutdown = true;
        }
        loggerThread.interrupt();
    }
}

public void log(String msg) throws InterruptedException {
    synchronized (lock) {
        if (shutdown || prepareShutdown)
            throw new IllegalStateException(/* ... */);
        ++reservations;
    }
    queue.put(msg);
}

private class LoggerThread extends Thread {
    public void run() {
        try {
            while (true) {
                try {
                    synchronized (lock) {
                        if (shutdown || prepareShutdown
                                && reservations == 0)
                            break;
                    }
                    String msg = queue.take();
                    synchronized (lock) {
                        --reservations;
                    }
                    writer.println(msg);

                } catch (InterruptedException e) { /* retry */
                }
            }
        } finally {
            writer.close();
        }
    }
}

}

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