Как обрабатывать Java InterruptedException без нарушения бизнес-логики? - PullRequest
2 голосов

Прежде всего, я читаю другой вопрос об этом элементе и знаю, как его использовать Thread.currentThread().interrupt();

Но проблема в том, что мне нужна моя бизнес-логика, даже если это исключение произошло. Насколько я понимаю, «InterruptedException» - это ситуация, когда ОС просит мой поток на некоторое время остановить выполнение, и после этого времени поток может продолжить выполнение. Я использую semaphore.acquire() и хочу повторить попытку «приобрести», если произошло исключение «InterruptedException». Мой код выглядит следующим образом:

  private final Semaphore semaphore = new Semaphore(1);
  ...

  private StorageConnection allocateConnection() {
        boolean allocated = false;
        while( !allocated ){
            try {
                semaphore.acquire();
                allocated = true;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }

        StorageConnection connection = connectionQueue.poll();
        // OTHER LOGIC
        return connection;
    }

Пожалуйста, дайте мне знать, если это правильный способ справиться с этой ситуацией или что мне делать, если это не так?

Заранее спасибо.

1 Ответ

1 голос
/ 11 декабря 2019

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

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

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

private StorageConnection allocateConnection() {
    boolean interrupted = false;
    boolean allocated = false;
    while( !allocated ){
        try {
            semaphore.acquire();
            allocated = true;
        } catch (InterruptedException e) {
            interrupted = true;
        }
    }

    StorageConnection connection = connectionQueue.poll();
    // OTHER LOGIC

    if (interrupted) {
        Thread.currentThread().interrupt();
    }

    return connection;
}

Неразумно просто очищать и игнорировать прерывание.

...