Ответы пользователя по тегу Linux
  • Как происходит остановка java приложения?

    @distrik
    Programador
    Один из классических способов обработки остановки java-приложения, как сказали выше - Runtime.getRuntime().addShutdownHook. В свою очередь в нем можно подать команду на остановку всем остальным потокам, либо используя флаг "interrupt" класса Thread, либо используя в рабочих потоках предусмотрительно заведенный собственный флаг остановки.

    Соответственно, останавливаемые потоки должны либо периодически проверять флаг остановки, либо корректно обрабатывать InterruptedException.

    Пример с флагом "interrupt"

    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
          Thread.getAllStackTraces().keySet().stream()
              //Не стоит останавливать поток в котором отрабатывает хук, а тем более пытаться заджойниться
              .filter(thread -> !thread.equals(Thread.currentThread()))
              //Демоны предполагают безопасное завершение в любой момент, останавливать их не нужно
              .filter(thread -> !thread.isDaemon())
              //Устанавливаем флаг "interrupt" для всех остальных 
              .peek(Thread::interrupt) 
              .peek(thread -> System.out.println(thread.getClass()))
              .forEach(thread -> {
                try {
                  thread.join(); //Ждем завершения всех потоков, которым установлен флаг "interrupt"
                } catch (InterruptedException e) {
                  // ...
                }
              });
        }));
        
        while (true) {
          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {
            System.out.println("Thread was interrupted once");
            //После перехвата исключения флаг "interrupt" возвращается в исходное состояние, поэтому его нужно установить снова
            Thread.currentThread().interrupt(); 
            break;
          }
        }
    
        while (true) {
          try {
            Thread.sleep(100); // Мы бы зависли здесь, если бы не установили флаг "interrupt" повторно
          } catch (InterruptedException e) {
            System.out.println("Thread was interrupted");
            Thread.currentThread().interrupt();
            break;
          }
        }
        
        while (!Thread.currentThread().isInterrupted()) {
          doSomeUninterruptableWork();
        }
      }
    Ответ написан
    1 комментарий