JavaRush /Курсы /Java Core /Создание и запуск новых нитей (трэдов)

Создание и запуск новых нитей (трэдов)

Java Core
6 уровень, 2 лекция
Открыта

— Привет, Амиго! Элли рассказала тебе о нитях, а я расскажу тебе о том, как с ними работать. Чтобы породить новую нить нужно:

1) Создать объект класса Thread (нить)

2) Передать в него объект, метод которого нужно выполнить

3) Вызвать у созданного объекта Thread метод start.

Пример:

Код Описание
class Printer implements Runnable {
    public void run() {
        System.out.println("I’m printer");
    }
}
Класс, который реализует интерфейс Runnable.
public static void main(String[] args) {
    Printer printer = new Printer();
    Thread childThread = new Thread(printer);
    childThread.start();
}
1 Создали объект класса Printer, который содержит метод run.
2 Создали новый объект класса Thread, передали ему в конструкторе объект printer, чей метод run()нужно будет исполнить.
3 Запустили новую нить в работу, вызовом метода start().

Маленькие программы на Java обычно состоят из одной нити, называемой «главной нитью» (main thread). Но программы побольше часто запускают дополнительные нити, их еще называют «дочерними нитями». Главная нить выполняет метод main и завершается. Аналогом такого метода main, для дочерних нитей служит метод run интерфейса Runnable.

— Ага, много нитей, много методов main.

Создание и запуск новых нитей (трэдов) - 1

— Чтобы указать, с какого именно метода нужно начать выполнение объекту Thread, нужно как-то передать метод этому объекту. В Java это реализовано с помощью интерфейса Runnable. Этот интерфейс содержит единственный абстрактный метод – void run(). Класс Thread имеет конструктор Thread(Runnable runnable), в который можно передать любой объект, который реализует интерфейс Runnable.

Ты должен унаследовать свой класс от интерфейса Runnable, затем переопределить метод run в своем классе. Именно с вызова этого метода начнется работа новой нити. В методе run ты можешь написать все, что хочешь.

Код Описание
class Printer implements Runnable {
    private String name;
    public Printer(String name) {
        this.name = name;
    }
    public void run() {
        System.out.println("I’m " + this.name);
    }
}
Класс, который реализует интерфейс Runnable.
public static void main(String[] args) {
    Printer printer1 = new Printer("Коля");
    Thread thread1 = new Thread(printer1);
    thread1.start();

    Printer printer2 = new Printer("Вася");
    Thread thread2 = new Thread(printer2);
    thread2.start();
}
Создаем две нити, каждая на основе своего объекта типа Printer.
public static void main(String[] args) {
    Printer printer = new Printer("Наташа");

    Thread thread1 = new Thread(printer);
    thread1.start();

    Thread thread2 = new Thread(printer);
    thread2.start();

    Thread thread3 = new Thread(printer);
    thread3.start();
}
Создаем три нити, на основе одного объекта Printer.

Более того, можно совместить это все в одном классе. Класс Thread унаследован от интерфейса Runnable, и достаточно просто переопределить его метод run:

Второй способ создания новой нити
class Printer extends Thread {
    private String name;
    public Printer(String name) {
        this.name = name;
    }
    public void run() {
        System.out.println("I’m " + this.name);
    }
}
Унаследовались от класса Thread, который реализует интерфейс Runnable, и переопределили метод run.
public static void main(String[] args) {
    Printer printer = new Printer("Вася");
    printer.start();

    Printer printer2 = new Printer("Коля");
    printer2.start();

}
Создаем две нити, каждая на основе своего объекта типа Printer.

— Это решение красивее.

— Да, но у него есть минусы:

1) Вам может понадобиться запустить несколько нитей на основе одного единственного объекта, как это сделано в «примере с Наташей».

2) Если вы унаследовались от класса Thread, вы не можете добавить еще один класс-родитель к своему классу.

3) Если у вашего класса есть класс-родитель, вы не можете добавить второго – Thread.

— Т.е. каждая из нитей после вызова метода start начнет выполнять метод run того объекта, который ему передали в конструкторе?

— Да. А если в конструкторе ничего не передали, то Thread просто исполняет свой внутренний метод run.

— А почему нельзя просто вызвать этот метод, например, так:

Код
public static void main(String[] args) {
    Printer printer1 = new Printer("Коля");
    printer1.run();
}

— Когда главная нить дойдет до метода run, наш «маленький роботик», просто зайдет внутрь и начнет исполнять все команды, которые там есть внутри, и только после их выполнения, вернется в метод main, и продолжит работу дальше. Создания второго «маленького робота» не произойдет, и вся работа будет делаться последовательно, а не параллельно (одновременно).

— Ясно. А можно вызвать какой-нибудь другой метод, а не run?

— Нет. Все привязано к интерфейсу Runnable, а он «знает» только об одном своем методе – run.

Комментарии (332)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Euraks Уровень 28
17 октября 2026
🦔
Maxim Terletsky Уровень 26
14 октября 2026
В Java существует три основных понятия, связанных с термином «поток»: 1. Поток ввода-вывода (InputStream/OutputStream) — последовательное чтение или запись данных. 2. Поток элементов (Stream<T>, Stream API) — последовательная обработка элементов: фильтрация, преобразование, сортировка, перебор. 3. Поток выполнения (Thread) — определяет, когда и какой код выполняется. После слова «поток» желательно указывать его назначение: «поток выполнения», «поток ввода-вывода», «поток элементов». Когда говорят «многопоточность», речь идёт о потоках выполнения. Многопоточность — это способность программы выполнять несколько потоков выполнения одновременно или конкурентно. Зачем нужна многопоточность? Современные процессоры имеют несколько ядер. Однопоточная программа использует только одно ядро, оставляя остальные простаивать. Многопоточность позволяет задействовать все ядра (при наличии нескольких ядер и поддержке со стороны ОС) и выполнять несколько задач параллельно или конкурентно, если ядро одно. Поток выполнения — это отдельная последовательность выполнения внутри одной программы. Каждый поток имеет собственный стек (локальные переменные, вызовы методов), но все потоки процесса используют общую кучу (heap) — именно поэтому возникают проблемы с общими данными. Поток выполнения представлен классом Thread. Способы запуска кода в отдельном потоке выполнения: 1. Наследование от Thread — объект потока создаётся через new MyThread(), а запускается через start() (не run() — иначе код выполнится в текущем потоке). 2. Реализация Runnable — задача передаётся в new Thread(runnable).start() или в ExecutorService.submit(runnable). Поток создаётся либо самим Thread, либо пулом. 3. Реализация Callable<V> — задача передаётся в ExecutorService.submit(callable), возвращается Future<V>. В отличие от Runnable, Callable возвращает результат и может бросать проверяемые исключения. Callable сам по себе не создаёт поток — его выполняет пул (или FutureTask, переданный в Thread).
Maxim Terletsky Уровень 26
14 октября 2026
P.S. Отдельное спасибо @Grigoryvvv за комментарий, связанный с термином «поток». Взял за основу для написания первой части текущего коммента. Поставьте Бэтмену лайк за его труд ❤️
Maxim Terletsky Уровень 26
15 октября 2026
P.P.S. Если копнуть глубже, нельзя не поблагодарить Ивана Головача за доходчивое объяснение того, как следует понимать термин «поток» в Java. Вот момент из его лекции
Grigoryvvv Уровень 28 Expert
28 августа 2026
28.08.2026 / 26 уровень Разделяют три разных понятия потоков: 1. InputStream / OutputStream... ↓ поток данных ввода-вывода - он отвечает за последовательное чтение или запись данных. InputStream - поток данных для чтения OutputStream - поток данных для записи 2. Stream<T> ↓ поток элементов для обработки (Stream API) - он отвечает за последовательную обработку элементов данных (фильтрацию, преобразование, сортировку, перебор и т. д.). 3. Thread ↓ поток выполнения - он отвечает за то, когда и какой код выполняется. У них совершенно разные API и предназначения. Просто исторически используют одно слово stream, которое можно перевести как «поток». Слово Thread в английском переводиться как нить, но по смыслу "нить информации" и "поток информации" очень близки, поэтому в разработке все называют его "потоком'. Главное после слова "поток" добавлять его назначение, к примеру "поток выполнения" или "поток данных для чтения" ... и тогда не будет путаницы во всех этих потоках и нитях 😁 Когда мы говорим «многопоточность» (multithreading), речь идёт именно о нескольких "потоках выполнения" (Thread), а не о InputStream, OutputStream или Stream<T>
19 февраля 2026
Последний комментарий без двух дней как пол года назад. Тут есть кто-нибудь?
FosTeR Уровень 51
22 февраля 2026
🖐
Сайфер Уровень 51
6 июля 2026
Есть. Уже давно курс прошел и стажировку тоже. Готовлюсь к собесам, перечитываю старые лекции.
Уровень 2
10 июля 2026
✊
Igor Perevalov Уровень 30
26 июля 2026
✋
Anonymous #3585174 Уровень 33
21 августа 2025
Like
Denzol255 Уровень 26
31 марта 2025
Ну какие нитки... Я понимаю, что в thread дословно переводиться как "нитка", но никто не говорит слово 'многонитейность' (язык сломаешь пока произнесешь). Поток, многопоточность, выполнить в отдельном потоке. На собесе засмеют же за "выполнить в отдельной нитке"...
SergeyPavlochev Уровень 29
29 мая 2025
Главное не путать с другим понятием, которое действительно является потоком, - а именно Stream. На собесе лучше говорить "тред", а не поток. А иначе возникнут вопросы про понимание того, что такое тред и что такое поток.
Grigoryvvv Уровень 28 Expert
28 августа 2026
Что на собесе говорить я выше написал ☝ Stream - поток элементов для обработки, а Thread - поток выполнения. И то и другое потоки, только совершенно разные, с разным предназначением.
TimDim Уровень 29
22 января 2025
Т.е. чтобы парализовать работу какойто программы системы ; можно создать Поток с прямым методом RUN и передать в него для реализации какой- то бесконечный цикл, правильно понимаю работу хаккерофф 🤔
Kim Уровень 14
2 марта 2025
Нет дружище, здесь не об этом. Просто RUN будет работать как обычный метод, без паралельности.
{Java_Shark} Уровень 36
11 октября 2024
++
Galis Gromyako Уровень 32
27 сентября 2024
Может кому-то поможет
Victor Kharchenko Уровень 14
29 марта 2025
Это ИИ сгенерировал или вручную конспект написан? Просто интересно...
Victor Уровень 48
8 апреля 2025
не помогло, но спасибо
Galis Gromyako Уровень 32
26 апреля 2025
Конспект
Антон Бушенев Уровень 23
2 мая 2024
Для тех кто задается вопросом про start and run, нашел это ниже: "Метод start() объекта Thread отвечает за создание нового потока и запуска метода run() у объекта в этом потоке.. Если же вызвать сразу метод run объекта, то исполнять его будет главный поток запущенный в методе main." скопировал у @Anonymous #3227998