Thread
Thread
API для потоков, которыми управляет JVM и ОС. Наследуется от Runnable
. Поток закончит выполнение когда завершится его метод run
.
val thread = Thread(
object: Runnable {
override fun run() {
// выполнение нового потока
}
}
)
thread.start()
isDaemon
Потоки-демоны используются для выполнения фоновых задач обслуживающих процесс в течение его жизни. Если завершается последний обычный поток в процессе - потоки-демоны будут завершены принудительно.
val thread = Thread {}
thread.isDaemon = true
thread.start()
interrupt
Метод прерывания потока. Методы приостанавливающие выполнение потока sleep
wait
join
при вызове прерывания сгенерируют InterruptedException
.
val thread = Thread {}
thread.interrupt() // прервать поток
thread.isInterrupted // проверить прерван ли поток. вызывается только изнутри потока
Thread.sleep
Приостанавливает выполнение потока в котором был вызван. Во время выполнения метода sleep
система перестает выделять потоку процессорное время распределяя его между другими потоками. Выполняется либо указанное количество времени либо пока не будет остановлен прерыванием.
val thread = Thread {
Thread.sleep(1000L)
}
Thread.yield
Переключает процессор на обработку других потоков.
while (!msgQueue.hasMessages()) { // пока в очереди нет сообщений
Thread.yield() // передать управление другим потокам
}
join
Механизм позволяющий одному потоку ждать завершения выполнения другого. В параметр можно указать время ожидания.
thread.join() // возвращает управление когда завершится ожидаемый поток
thread.join(1000L) // возвращает управление когда завершится ожидаемый поток или закончится время
Priority
Каждый поток в системе имеет свой приоритет. Система в первую очередь выполняет потоки с большим приоритетом, а потоки с меньшим приоритетом получают процессорное время только тогда, когда их более привилегированные собратья простаивают.
MIN_PRIORITY | Минимальный приоритет. |
NORM_PRIORITY | Дефолтный умолчанию. |
MAX_PRIORITY | Максимальный приоритет. |
thread.priority = Thread.MAX_PRIORITY
isAlive
Возвращает true если поток выполняется и false если поток завершен или не был запущен.
thread.isAlive
name
Задать имя потока. Помогает понять какой поток выполняет некоторое действие.
thread.name = "MyThread"
id
Возвращает идентификатор потока. Это уникальное число присвоенное потоку.
thread.id
Thread.currentThread
Возвращает объект потока в котором вызван.
val thread = Thread {
Thread.currentThread()
}
Вопросы на собесе (9)
- Как создать новый поток с использованием класса Thread?
Создать подкласс
Thread
или передать объектRunnable
в конструкторThread
. Затем вызватьstart()
для запуска потока.
- Зачем нужен метод join и когда его следует использовать?
Метод
join
заставляет текущий поток ждать завершения другого потока, чтобы убедиться, что его выполнение завершилось до продолжения работы текущего потока.
- Как управлять приоритетом потоков в Java?
Приоритет потоков в Java управляется методом
setPriority
классаThread
, который принимает значения отThread.MIN_PRIORITY
доThread.MAX_PRIORITY
.
- Как работают методы yield и interrupt?
•
yield
приостанавливает текущий поток, чтобы другие потоки могли выполниться.•
interrupt
прерывает выполнение потока и вызываетInterruptedException
, если поток заблокирован.
- Что будет со 2 потоком который пытается получить доступ к ресурсу занятым 1 потоком?
Будет ждать, пока 1 освободит ресурс.
- Ресурс занят 1 потоком. 2 и 3 хотят получить доступ, какой из них получит?
Любой из них.
- Почему доступ к освободившемуся ресурсу получает рандомный поток, а не первый в очереди?
Из-за особенностей реализации синхронизации в JVM. Это связано с использованием стратегий, которые не гарантируют порядок FIFO, оптимизацией производительности и состоянием потоков, что влияет на выбор пробуждаемого потока.
- Как пробудить поток, чтобы он перестал ждать доступа к ресурсу?
Вызвать методы
notify()
илиnotifyAll()
на объекте блокировки.
- Корректно ли написан код будет ли работать?
class Scheduler { val jobs = mutableListOf<() -> Unit>() init { thread { while (true) { for (job in jobs) job() } } } fun schedule(job: () -> Unit) { jobs += job } } val sch = Scheduler() thread { sch.schedule { println("hello") } } thread { sch.schedule { println("world") } }
Код не корректен из-за отсутствия синхронизации при доступе к
jobs
, что может привести к ошибкам, и бесконечного цикла без задержек, что перегружает процессор.