Класс Thread
Класс java.lang.Thread — основной строительный блок многопоточности в Java.
Каждый экземпляр Thread представляет отдельный поток выполнения, который
может работать параллельно с главным потоком программы (main). С помощью
потоков можно одновременно опрашивать датчики, обрабатывать данные и обновлять
интерфейс — это особенно полезно для проектов AlashEd, где, например, один
поток читает ультразвуковой датчик, а другой управляет моторами.
Создать поток можно двумя способами: расширить класс Thread и переопределить
метод run(), либо передать объект Runnable в конструктор Thread.
Метод start() запускает поток — после этого JVM вызывает run() уже
в отдельном потоке. Напрямую вызывать run() нельзя — это будет обычный
вызов метода в текущем потоке.
Синтаксис
class MyThread extends Thread {
@Override
public void run() {
// код, выполняющийся в новом потоке
}
}
// запуск
MyThread t = new MyThread();
t.start(); // правильно
// t.run(); // НЕПРАВИЛЬНО — выполнится в текущем потоке
Пример 1. Простейший поток
public class HelloThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println("Поток: шаг " + i);
}
}
public static void main(String[] args) throws InterruptedException {
HelloThread t = new HelloThread();
t.start();
t.join();
System.out.println("main завершён");
}
}
Output:
Поток: шаг 1
Поток: шаг 2
Поток: шаг 3
main завершён
Пример 2. Два параллельных потока
public class TwoThreads extends Thread {
private final String name;
public TwoThreads(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(name + " - " + i);
try { Thread.sleep(100); } catch (InterruptedException e) { return; }
}
}
public static void main(String[] args) {
new TwoThreads("A").start();
new TwoThreads("B").start();
}
}
Output (порядок может различаться):
A - 1
B - 1
A - 2
B - 2
A - 3
B - 3
Пример 3. Имя и приоритет потока
public class ThreadInfo extends Thread {
@Override
public void run() {
System.out.println("name=" + getName()
+ ", priority=" + getPriority()
+ ", id=" + getId());
}
public static void main(String[] args) {
ThreadInfo t = new ThreadInfo();
t.setName("Sensor-Reader");
t.setPriority(Thread.MAX_PRIORITY);
t.start();
}
}
Output:
name=Sensor-Reader, priority=10, id=21
Пример 4. Sleep и пауза
public class SleepDemo extends Thread {
@Override
public void run() {
for (int i = 3; i >= 1; i--) {
System.out.println("Старт через " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
System.out.println("Поехали!");
}
public static void main(String[] args) {
new SleepDemo().start();
}
}
Output:
Старт через 3
Старт через 2
Старт через 1
Поехали!
Пример 5. Daemon-поток
Демон-потоки не препятствуют завершению JVM — они часто используются для фоновых задач: логирование, периодический опрос датчиков.
public class DaemonDemo extends Thread {
@Override
public void run() {
while (true) {
System.out.println("daemon tick");
try { Thread.sleep(200); } catch (InterruptedException e) { return; }
}
}
public static void main(String[] args) throws InterruptedException {
DaemonDemo d = new DaemonDemo();
d.setDaemon(true);
d.start();
Thread.sleep(600);
System.out.println("main завершён, daemon будет убит JVM");
}
}
Output:
daemon tick
daemon tick
daemon tick
main завершён, daemon будет убит JVM
Подводные камни
Предупреждение
Вызов run() напрямую не создаёт нового потока — код выполнится синхронно
в текущем потоке. Используйте только start().
Предупреждение
Один и тот же объект Thread нельзя запустить дважды — повторный вызов
start() бросает IllegalThreadStateException.
Совет
Расширять Thread оправдано лишь когда вам действительно нужно
переопределить поведение потока. Чаще предпочтительнее реализовать
Runnable или использовать ExecutorService — это гибче и тестируемее.
См. также
Примечание
Материал подготовлен на основе раздела «Concurrency» из Oracle Java Tutorials (docs.oracle.com/javase/tutorial/essential/concurrency/) и распространяется в соответствии с Oracle Free Documentation License. Тексты и примеры кода написаны заново на русском языке для AlashEd Wiki.