предисловие
Текст был включен в мой репозиторий GitHub, добро пожаловать, звезда:GitHub.com/bin39232820…
Лучшее время посадить дерево было десять лет назад, затем сейчас
Я знаю, что многие люди не играютqqТеперь, но с ностальгией, добро пожаловать в группу Six Meridian Excalibur по изучению Java для новичков, номер группового чата:549684836Поощряйте всех вести блог на пути к технологиям
болтовня
Многопоточная серия была написана много раньше.Если вам интересно, вы можете зайти на мой склад Kangkang.Что насчет сегодняшнего дня? Я также видел, что другие люди писали хорошо, а затем случайно скопировал их, ха-ха, на самом деле, я просто записал то, что увидел. Если вы напишете это сами, это может быть более запоминающимся.
Диаграмма перехода состояния потока
- НОВОЕ начальное состояние
- RUNNABLE рабочее состояние
- БЛОКИРОВАНО состояние блокировки
- ОЖИДАНИЕ состояние ожидания
- Время ожидания тайм-аута TIME_WAITING
- TERMINATED прекращен статус
Уведомление: Поток, вызывающий obj.wait(), должен сначала получить монитор obj, а wait() освободит монитор obj и войдет в состояние ожидания. Так что wait()/notify() следует использовать в сочетании с synchronized.
разница между блокировкой и ожиданием
Блокировка: когда поток пытается получить блокировку объекта (не java.util.concurrent блокировку библиотеки, т. е. синхронизированную), а блокировка удерживается другим потоком, поток переходит в состояние блокировки. Его характеристика заключается в том, что он прост в использовании, и планировщик JVM решает проснуться сам, без необходимости явного пробуждения другого потока и не отвечает на прерывания.
Блокировка Состояние, в котором поток заблокирован в ожидании блокировки критической секции.
Ожидание: когда поток ожидает, пока другой поток уведомит планировщик об условии, поток переходит в состояние ожидания. Его характеристика заключается в том, что ему нужно явно ожидать пробуждения другого потока, который является гибким в реализации, имеет более богатую семантику и может реагировать на прерывания. Например, вызов: Object.wait(), Thread.join() и ожидание блокировки или условия. Ожидание входа потока в блокировку, но нужно ждать, пока другие потоки что-то сделают
Следует подчеркнуть, что хотя и synchronized, и Lock в JUC реализуют функцию блокировки, состояние, в которое входит поток, отличается. Synchronized заставит поток войти в состояние блокировки, в то время как Lock в JUC использует LockSupport.park()/unpark() для достижения блокировки/пробуждения, что заставит поток перейти в состояние ожидания. Но опять же, хотя состояние, в которое они входят в ожидании блокировки, отличается, но после пробуждения все они входят в состояние runnable, которое одинаково с точки зрения поведенческих эффектов. Поток входит в блокировку, но должен ждать, пока другие потоки что-то сделают
основная операция
start()
Новый поток выполняет свой метод run(), а поток может быть запущен только один раз. В основном путем вызова собственного start0 () для достижения.
public synchronized void start() {
     //判断是否首次启动
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
       //启动线程
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
private native void start0();
run()
Пользователь не должен вызывать метод run().После запуска потока через метод запуска, когда поток получает время выполнения ЦП, он входит в тело метода запуска для выполнения определенных задач. Обратите внимание, что наследование класса Thread должно переопределять метод запуска и определять конкретные задачи, которые должны выполняться в методе запуска.
sleep()
Существуют две перегруженные версии метода сна.
sleep(long millis) //参数为毫秒
sleep(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒
sleep эквивалентен переводу потока в спящий режим, передаче ЦП и предоставлению ему возможности выполнять другие задачи.
Но важно отметить, что метод sleep не освобождает блокировку, то есть, если текущий поток удерживает блокировку объекта, даже если вызывается метод sleep, другие потоки не могут получить доступ к объекту.
yield()
Вызов метода yield приведет к тому, что текущий поток передаст разрешение ЦП, что позволит ЦП выполнять другие потоки. Это похоже на метод сна, который также не снимает блокировку. Однако yield не может контролировать конкретное время передачи ЦП, кроме того, метод yield может разрешить только потокам с одинаковым приоритетом иметь возможность получить время выполнения ЦП.
Обратите внимание, что вызов метода yield не переводит поток в состояние блокировки, а возвращает поток в состояние готовности, ему нужно только подождать, чтобы повторно получить время выполнения ЦП, которое отличается от метода сна.
join()
Метод соединения имеет три перегруженные версии.
1 join()
2 join(long millis) //参数为毫秒
3 join(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒
join() на самом деле использует wait(), но ему не нужно ждать notify()/notifyAll(), и он на него не влияет. Условия для его завершения: 1) время ожидания истекло; 2) целевой поток был запущен (судя по isAlive()).
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
//0则需要一直等到目标线程run完
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
//如果目标线程未run完且阻塞时间未到,那么调用线程会一直等待。
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
interrupt()
Эта операция установит бит флага прерывания потока Что же касается того, что делает поток, это зависит от потока.
- Если поток sleep(), wait(), join() и т. д. заблокирован, поток будет периодически проверять бит состояния прерывания. вызовы, и исключение будет сгенерировано. Сразу же после возникновения исключения бит состояния прерывания потока очищается, то есть сбрасывается в значение false. Исключения генерируются, чтобы вывести поток из заблокированного состояния и дать программисту достаточно времени для обработки запросов на прерывание перед завершением потока.
- Если поток работает, соревнуясь за синхронизацию, блокировку() и т. д., то он непрерывен, и они его игнорируют.
О прерываниях можно судить тремя способами:
-
isInterrupted()
Этот метод только считывает флаг прерывания потока и не сбрасывает его.
-
interrupted()
Этот метод считывает флаг прерывания потока и сбрасывает его.
-
throw InterruptException
Когда возникает это исключение, бит флага прерывания сбрасывается.
конец
Сяо Люлю считает, что самое важное — понять разницу между двумя состояниями блокировки и ожидания.
Автор статьиДетали потока
ежедневные комплименты
Хорошо всем, вышеизложенное является полным содержанием этой статьи. Люди, которые могут видеть это здесь, всенастоящий порошок.
Творить нелегко. Ваша поддержка и признание — самая большая мотивация для моего творчества. Увидимся в следующей статье.
Six Meridians Excalibur | Text [Original] Если в этом блоге есть какие-то ошибки, прошу покритиковать и посоветовать, буду очень признателен!