Может кто-нибудь помочь объяснить вывод этих 2 потоков?

public class Join1 {
    public static void main(String[] args) {
        Thread t = new Thread() {
            public void run() {
                System.out.print("EnterValue:");
                try {
                    System.in.read();
                } catch (Exception ex) {}
                System.out.println("Thread Finished.");
            }
        };
        System.out.println("Starting Thread");
        t.start();
        System.out.println("Joining");
        try {
            t.join();
        } catch (Exception ex) {}
        System.out.println("Main Finished.");
    }
}

Выход

Начальный поток

Присоединение

Введите значение:

Тема завершена

Главная Готовая

public class Join2 {
        public static void main(String[] args) {
            Thread t = new Thread() {
                public void run() {
                    System.out.println("EnterValue:");
                    try {
                        System.in.read();
                    } // thread blocked
                    catch (Exception ex) {}
                    System.out.println("Thread Finished.");
                }
            };

            System.out.println("Starting Thread");
            t.start();
            try {
                Thread.sleep(2000);
            } catch (Exception e) {}
            System.out.println("No Join");
            System.out.println("Main Finished.");
        }
    }

Выход

Начальный поток

Введите значение:

Нет присоединения

Главная Готовая

3 (вход)

Тема завершена

Я не понимаю порядок некоторых из этих выходных данных. Например, в Join2, почему он выводит готовые строки в основном, прежде чем вы вводите свое значение?

Что мешает main закончить пример 2?

Joe C 24.04.2018 23:54

Поскольку потоки не блокируют основную программу, они находятся в отдельных потоках, которые не блокируются.

Spencer Wieczorek 24.04.2018 23:54

Кроме того, я настоятельно рекомендую не принимать исключения (catch (Exception ex) {}). вы должны, как минимум, сделать ex.printStackTrace(). Это может даже способствовать возникновению вашей проблемы (у нас нет возможности узнать).

Joe C 24.04.2018 23:57

Это из заметок учителя. Я просто хочу знать, почему порядок вывода такой, как есть

JohnBanter 25.04.2018 00:02

@JohnBanter Я бы посоветовал вам изучить, что такое потоки и как они работают. Я сказал вам почему в моем последнем комментарии. Думайте о каждом потоке как о его собственной независимой подпрограмме, созданные вами потоки не мешают завершению основного потока. Из-за этого он завершит работу в основном потоке и будет ожидать ввода в созданные вами.

Spencer Wieczorek 25.04.2018 00:23
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
49
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Единственное различие в двух приведенных примерах - это метод, вызываемый после запуска потока с t.start().

Join1.java вызывает Thread.join(), который, судя по документации, говорит: «Ожидает, пока этот поток умрет». Таким образом, только после завершения метода выполнения потока (после завершения System.in.read()) выполняется «Main Finished». Распечатать"

Join2.java вызывает Thread.sleep(2000), который приостанавливает поток на 2000 миллисекунд. Попробуйте закомментировать эту строку и посмотреть результат. Кроме того, обратите внимание, что программа не закрывается после того, как напечатает «Main Finished». Поток все еще ожидает ввода.

TL; DR;

Thread.join() делает основную паузу, пока этот поток не завершится.

Thread.sleep(2000) приостанавливает основной поток только на 2 секунды перед продолжением, другой поток продолжает выполняться.

Re, «... приостанавливает поток» (или «блокирует поток», или «засыпает (sic.) Поток» и т. д.). Некоторые из этих слов являются камнем преткновения для новичков, которые еще не совсем поняли концепции. Иногда они получают это быстрее, если вы говорите: «Thread.sleep(2000)ничего не делает, но подождите две секунды». или «t.join()ничего не делает, но дождаться завершения потока t». Последний особенно полезен, потому что многие новички откуда-то получают ошибочное представление о том, что t.join() выполняет что-нибудь для потока t.

Solomon Slow 25.04.2018 03:02

Думайте о потоках как о параллельных выполнениях. К тому времени, когда вы вернетесь из .start () в основной поток, новый поток будет свободен, хорошо. Но в Join2 вы не говорите основному потоку ждать завершения потока t. Так что за 2 секунды он проходит мимо сна.

Другие вопросы по теме