Всегда ли плохо блокировать основной метод в Java? - PullRequest
0 голосов
/ 17 января 2020

У нас есть приложение, которое постоянно работает. В основном методе ничего не происходит, кроме инициализации нескольких фоновых потоков. Фоновые потоки обрабатывают события сокета по мере их возникновения. Помимо времени обработки событий сокета, приложение остается в состоянии ожидания.

Main

  • Start Thread 1 -> while (соединение с сокетом 1 исправно) -> process события
  • Запуск потока 2 -> время (соединение с сокетом 2 исправно) -> события процесса
  • Запуск потока 3 -> время (соединение с сокетом 3 исправно) -> события процесса
  • Запуск потока 4 -> время (хорошее соединение с сокетом 4) -> события процесса
while (true); // block main thread from exiting. Otherwise, periodic GC calls kills the app.

Поскольку основная функция моего приложения заключается в обработке событий, а передние задачи не выполняются, так как например. В моем случае плохая блокировка основного потока? Какие есть другие альтернативы?

Ответы [ 4 ]

2 голосов
/ 18 января 2020

основной поток является просто первым потоком, и, как таковой, не отличается от любого другого потока. Если вы заблокируете его, это означает потерю памяти, занятую этим потоком (около 1 МБ), и больше ничего. Поэтому я бы просто вернулся из метода main, если для этого потока нет работы.

Я заметил комментарий в вашем коде: заблокировать выход из основного потока. В противном случае периодические c G C звонки убивают приложение . Комментарий неверный. G C звонки не могут убить приложение. Я подозреваю, что другие потоки запускаются в режиме демона, и поэтому процесс включения не ожидает их завершения sh.

Если вы опишите более подробно, когда весь процесс должен закончиться, мы могли бы дать более разумные советы.

1 голос
/ 17 января 2020

Да, это плохой дизайн. Используйте ExecutorService и добавьте к нему потоки.

1 голос
/ 17 января 2020

Блокировки в основном методе (или из любого другого потока) следует избегать. Проблема, с которой вы сталкиваетесь - как создать некоторые потоки и поддерживать работу JVM до тех пор, пока эти потоки не завершатся sh, - может быть решена лучшими способами.

Если вы создадите новый Thread и позвоните setDaemon (false) , тогда вам не нужно ничего делать со сном или ожиданием. Установив, что поток не является демоном, JVM будет работать до тех пор, пока этот поток не завершится. Из Javado c:

Виртуальная машина Java завершает работу, когда все запущенные потоки - все потоки демона.

Вот пример класса потока, который пытается спать в течение 2 секунд, затем выводит сообщение:

class ExampleThread extends Thread {
    @Override
    public void run() {
        try {
            sleep(2000);
            System.out.println("done sleeping");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Если вы называете это так - установив daemon в false - вы сначала увидите вывод thread started, затем 2 секунды ничего, затем output done sleeping.

public static void main(String[] args) {
    ExampleThread t = new ExampleThread();
    t.setDaemon(false);
    t.start();

    System.out.println("thread started");
}

Если вы замените t.setDaemon(false) на этот t.setDaemon(true) - так, чтобы новый поток был фактически потоком демона - тогда вы увидите вывод thread started, за которым следует непосредственная JVM завершение.

1 голос
/ 17 января 2020

Поскольку ваш основной поток занят ожиданием, ему потребуется планировщик потоков (основной поток) в список запланированных потоков. И если ваша машина, на которой вы запускаете приложение, имеет менее 4 процессоров, то пострадают ваши потоки обработки событий.

Существует множество других способов заблокировать ваш основной поток без ожидания ожидания. Thread.join() как упомянуто выше, является одним из них. Вы также можете использовать Future.get() или ExecutorService.awaitTermination(), если вы используете высокоуровневые объекты параллелизма.

...