Comments 10
Несколько замечаний из тех, что сразу бросаются в глаза:
"Программа завершается когда Main Thread выполнит метод main()" - неверно. Программа написанная на Java завершится, как только завершится последний её поток не являющийся демоном. Метод main() при этом может быть уже давным-давно завершен.
"Функциональный интерфейс Runnable содержит единственный абстрактный метод run()
который запускает новый поток выполнения." - метод run() НЕ запускает новый поток. Он запускается В новом потоке (предварительно созданном).
Спасибо! Дополнил формулировки:
"Программа завершается, когда Main Thread выполнит метод main()
и все дочерние не daemon треды выполнят свои методы run()"
"Функциональный интерфейс Runnable содержит единственный абстрактный метод run()
в котором будет реализована логика выполнения нового потока."
Так вроде бы при запуске java-процесс, метод main() начинает свою работу, а дальше уже от него начинают создаваться потоки, т.е. создаётся древовидная структура. Т.к. метод main() это корень, то он не может закончиться, пока его дочерние потоки не завершаться, иначе наступит момент неопределённость для дочерних потоков.
Поэтому, если я правильно понял "... как только завершится последний её поток не являющийся демоном. Метод main() при этом может быть уже давным-давно завершен", то всё же, наверно, получается метод main(), скорее всего, НЕ может быть завершённым при присутствии каких-либо других потоков не демонов, потому что они его дочерние потоки. Он может завершить свою основную работу, но он тогда просто перейдёт в режим Pending и будет ожидать завершения своих дочерних потоков. Но он не будет же Terminated.
Поэтому метод main() первый запустился и последний завершиться из-за древовидной структуры.
Потоки - это независимые друг от друга сущности. Не знаю, откуда Вы взяли информацию об иерархии (скорее всего путаете с другим языком).
Код ниже выведет в консоль: main -> TERMINATED
public class Main {
public static void main(String[] args) throws Exception {
Thread main = Thread.currentThread();
Thread child = new Thread(() -> {
try {
Thread.sleep(2000);
System.out.println(main.getName() + " -> " + main.getState());
} catch(Exception e) {
e.printStackTrace();
}
});
child.start();
}
}
И ещё момент - у Java потоков нет состояния Pending (в смысле - вообще нет).
Так вроде бы при запуске java-процесс, метод main() начинает свою работу, а дальше уже от него начинают создаваться потоки, т.е. создаётся древовидная структура. Т.к. метод main() это корень, то он не может закончиться, пока его дочерние потоки не завершаться, иначе наступит момент неопределённость для дочерних потоков.
Вы немного путаете. Когда вы запускаете программу на Java - вы запускаете JVM а уже JVM, в дальнейшем когда будет готова, запускает Вашу программу посредством вызова main(). Это просто главная точка входа для пользовательского приложения, не более.
Переключение происходит сотни раз в секунду (тактовая частота),
Ну откуда там тактовая? Тактовая делить на 10 миллионов, скорее.
В первом случае программа называются Однопоточной
Во втором, если потоков несколько – Многопоточной
(когда независимо друг от друга выполняются разные части кода)
Неверно. Различия в названиях - не от количества ядер, а от количества потоков в самой программе.
Спасибо, интересно было почитать )
Я бы еще добавил про volatile. Ну и, наверное, про Callable и Future тоже могут на собесах поинтересоваться.
Спасибо за замечания!
Добавил в статью 3 раздела по этим темам:
Модификатор volatile
Интерфейсы Callable и Future
Класс CompletableFuture
Присоединиться к потоку
join()
Свое выполнение начнёт выбранный поток.
Выполнение текущего потока будет приостановлено.
Не начнёт. Он должен быть уже запущен. Здесь же мы просто ожидаем, когда он завершит выполнение. А если поток не был запущен, то join сразу завершит своё выполнение.
Статический метод
Thread.interrupted()
возвращает значение флага прерывания для текущего потока. После проверки всегда присваивает значение флагаfalse
и запускает поток.Метод
isInterrupted()
возвращает значение флага прерывания для того объекта, на котором вызван. Не запускает поток.
Какой поток? Зачем запускает?
Многопоточность Java. #неОпятьАСнова #javaJunior #javaCore