Что такое поток (Thread) в Java?

Ответ

Поток (Thread) в Java — это наименьшая единица выполнения внутри процесса. Потоки одного процесса разделяют его память (кучу) и системные ресурсы, но имеют собственные стеки вызовов и программные счетчики, что позволяет выполнять несколько задач параллельно.

Способы создания потока:

  1. Наследование от класса Thread:
    class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("Поток выполняется: " + getName());
        }
    }
    // Запуск
    new MyThread().start();
  2. Реализация интерфейса Runnable (предпочтительнее):
    class MyTask implements Runnable {
        @Override
        public void run() {
            System.out.println("Задача выполняется");
        }
    }
    // Запуск
    Thread thread = new Thread(new MyTask());
    thread.start();

Жизненный цикл потока (состояния): NEW -> RUNNABLE -> (BLOCKED, WAITING, TIMED_WAITING) -> TERMINATED.

Ключевые особенности:

  • Совместная память: Потоки имеют общий доступ к объектам в куче, что требует синхронизации (ключевое слово synchronized, классы из java.util.concurrent).
  • Управление: Планирование потоков осуществляется JVM и операционной системой.
  • Приоритеты: Можно задавать, но они являются рекомендациями для планировщика.
  • Daemon-потоки: Фоновые потоки, которые не препятствуют завершению работы JVM (например, сборщик мусора).

Ответ 18+ 🔞

Давай разберём эту тему, а то я вижу, у тебя глаза уже стекленеют от этих казённых формулировок. Поток в Java — это, по сути, отдельный мудак внутри твоего приложения, который может делать своё дело, пока другие мудаки делают своё. Все они живут в одной квартире (это процесс), делят один холодильник (это куча, общая память), но у каждого своя комната (стек) и свои тараканы в голове (программный счётчик). Идея в том, чтобы не ждать, пока один допиздится, а городить всё параллельно.

Как этих мудаков создавать, есть два основных способа:

  1. Наследоваться от Thread. Классика, но уже не в моде, потому что наследование — это одно место, а ты можешь захотеть быть в нескольких местах сразу, понимаешь?

    class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("Поток выполняется: " + getName());
        }
    }
    // Запускаем его в свободное плавание
    new MyThread().start();
  2. Реализовать Runnable. Это сейчас модно и правильно. Отделяешь задачу (Runnable) от работяги (Thread). Одна задача — много работяг. Гибко, блядь!

    class MyTask implements Runnable {
        @Override
        public void run() {
            System.out.println("Задача выполняется");
        }
    }
    // Нанимаем работягу и даём ему задание
    Thread thread = new Thread(new MyTask());
    thread.start();

А теперь про жизнь потока, она грустная и предсказуемая: Рождается (NEW), потом его запускают и он готов к работе (RUNNABLE). А дальше — пиздец. Либо он работает, либо его посылают в блокировку (BLOCKED), либо он сидит и ждёт у моря погоды (WAITING), либо ждёт, но с таймером, как я в очереди в поликлинике (TIMED_WAITING). Кончается всё всегда одинаково — смертью (TERMINATED). Весь цикл, ёпта.

Важные моменты, без которых огребешь:

  • Общая память — это пиздец. Раз все потоки лезут в один холодильник, начинается драка. Один взял последнюю котлету, другой тоже хочет. Нужна синхронизация — ставить замки (synchronized) или использовать умные штуки из java.util.concurrent. Без этого получишь race condition, а это когда результат работы программы зависит от того, кто из потоков сегодня больше выпил. Нестабильная хуйня.
  • Кто главный? Ты-то создал потоки, но командовать ими будет планировщик операционки и JVM. Ты можешь только попросить, задав приоритет. Но это как просить соседа не сверлить в субботу — результат непредсказуем.
  • Демоны (Daemon). Это такие потоки-призраки. Пока в доме есть хотя бы один обычный жилец (пользовательский поток), они тихо делают свою работу (как сборщик мусора). Но стоит всем нормальным потокам завершиться — демонов вышвыривают нахуй без церемоний, даже если они не закончили. Жестоко, но так надо.

Вот, коротко и с характером. Главное — помни про синхронизацию, а то эти потоки тебе всю программу в говно превратят.