Разница между состояниями WAIT и BLOCKED
В чем разница между состоянием состояния WAIT и состоянием BLOCKED?
Документация Thread.State :
блокированный
В этом состоянии находится stream, заблокированный в ожидании блокировки монитора.
- Как у вас пародия на пару секунд в андроиде?
- Тайм-аут сеанса в ASP.NET
- Вызов IllegalMonitorStateException при вызове wait ()
- Как настроить тайм-аут подключения сокетов
- Таймаут запроса Tomcat
ждущий
Нить, которая бесконечно ждет другого streamа для выполнения определенного действия, находится в этом состоянии
не объясняет мне разницу.
- Java: установить таймаут на определенный блок кода?
- C ++: Как реализовать тайм-аут для вызова произвольной функции?
- дождитесь, пока все streamи закончат работу в java
- Как изменить время ожидания тайм-аута запроса nodejs?
- Время ожидания ответа Express.js
- Тайм-аут аутентификации форм против сеанса
- Тайм-ауты услуг WCF
Поток переходит в состояние ожидания, когда он вызывает wait()
для объекта. Это называется Ожидающее состояние. Как только stream достигнет состояния ожидания, ему нужно будет подождать, пока какой-нибудь другой stream не notifyAll()
или notifyAll()
на объект.
Как только этот stream будет уведомлен, он не будет запущен. Возможно, другие streamи также уведомлены (используя notifyAll()
), или первый stream не завершил свою работу, поэтому он по-прежнему блокируется, пока не получит свой шанс. Это называется заблокированным состоянием.
После того, как останутся другие streamи и вероятность этого streamа, он переходит в состояние Runnable после того, как он имеет право подобрать работу на основе механизма streamов JVM и переходит в состояние запуска.
Разница относительно проста.
В состоянии BLOCKED
stream собирается ввести synchronized
блок, но есть еще один stream, который в настоящее время выполняется внутри synchronized
блока на одном и том же объекте. Первый stream должен ждать, пока второй stream выйдет из своего блока.
В состоянии WAITING
stream ожидает сигнал из другого streamа. Обычно это происходит путем вызова Object.wait()
или Thread.join()
. Затем stream будет оставаться в этом состоянии, пока другой stream не Object.notify()
или не умрет.
Упрощенная перспектива для интерпретации дампов streamов:
- ЖДИТЕ – Я жду, чтобы мне дали какую-то работу, поэтому я сейчас простаиваю.
- BLOCKED. Я занят попыткой выполнить работу, но на моем пути стоит еще один stream, поэтому я сейчас простаиваю.
- RUNNABLE … (Native Method) – я вызвал, чтобы запустить какой-то собственный код (который еще не закончен), поскольку JVM имеет значение RUNNABLE, и он не может дать никакой дополнительной информации. Общим примером может быть собственный метод прослушивания сокетов, закодированный в C, который на самом деле ждет, пока какой-либо трафик не поступит, поэтому я сейчас простаиваю. В этой ситуации это можно рассматривать как особый вид WAIT, поскольку мы на самом деле не работаем (без процессора), но вам придется использовать дамп streamа операционной системы, а не дамп streamа Java, чтобы увидеть его.
Важным отличием между заблокированным и ожидающим состояниями является влияние на планировщик. Нить в заблокированном состоянии является частью waitset, борющейся за блокировку; этот stream по-прежнему считается чем-то, что планировщик должен обслуживать, возможно, принимая во внимание решения планировщика о том, сколько времени требуется для выполнения текущих streamов.
Как только stream находится в состоянии ожидания, стресс, который он накладывает на систему, сведен к минимуму, и планировщику не нужно беспокоиться об этом. Он неактивен, пока не получит уведомление. За исключением того факта, что он поддерживает занятие ОС, он полностью не работает.
Именно поэтому использование notifyAll менее чем идеально, оно вызывает кучу streamов, которые ранее были счастливыми, не загружая систему, чтобы проснуться, где большинство из них будет блокироваться, пока они не смогут получить блокировку, найти условие, в котором они находятся ожидание – это неправда, и вернитесь к ожиданию. Было бы предпочтительнее уведомлять только те streamи, которые имеют шанс добиться прогресса.
(Использование ReentrantLock вместо встроенных блокировок позволяет вам иметь несколько условий для одной блокировки, так что вы можете удостовериться, что уведомленный stream – это тот, который ожидает определенного условия, избегая ошибки с потерянным уведомлением в случае уведомления о streamе то, на что он не может действовать.)
Blocked-Your thread находится в состоянии выполнения жизненного цикла streamа и пытается получить блокировку объекта. Wait – ваш stream находится в состоянии ожидания жизненного цикла streamа и ожидает, что сигнал уведомления войдет в текущее состояние streamа.
см. этот пример:
демонстрация состояний streamов.
/*NEW- thread object created, but not started. RUNNABLE- thread is executing. BLOCKED- waiting for monitor after calling wait() method. WAITING- when wait() if called & waiting for notify() to be called. Also when join() is called. TIMED_WAITING- when below methods are called: Thread.sleep Object.wait with timeout Thread.join with timeout TERMINATED- thread returned from run() method.*/ public class ThreadBlockingState{ public static void main(String[] args) throws InterruptedException { Object obj= new Object(); Object obj2 = new Object(); Thread3 t3 = new Thread3(obj,obj2); Thread.sleep(1000); System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+ ",when Wait() is called & waiting for notify() to be called."); Thread4 t4 = new Thread4(obj,obj2); Thread.sleep(3000); System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+",After calling Wait() & waiting for monitor of obj2."); System.out.println("nm:"+t4.getName()+",state:"+t4.getState().toString()+",when sleep() is called."); } } class Thread3 extends Thread{ Object obj,obj2; int cnt; Thread3(Object obj,Object obj2){ this.obj = obj; this.obj2 = obj2; this.start(); } @Override public void run() { super.run(); synchronized (obj) { try { System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before Wait()."); obj.wait(); System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After Wait()."); synchronized (obj2) { cnt++; } } catch (InterruptedException e) { e.printStackTrace(); } } } } class Thread4 extends Thread{ Object obj,obj2; Thread4(Object obj,Object obj2){ this.obj = obj; this.obj2 = obj2; this.start(); } @Override public void run() { super.run(); synchronized (obj) { System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before notify()."); obj.notify(); System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After notify()."); } synchronized (obj2) { try { Thread.sleep(15000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
./*NEW- thread object created, but not started. RUNNABLE- thread is executing. BLOCKED- waiting for monitor after calling wait() method. WAITING- when wait() if called & waiting for notify() to be called. Also when join() is called. TIMED_WAITING- when below methods are called: Thread.sleep Object.wait with timeout Thread.join with timeout TERMINATED- thread returned from run() method.*/ public class ThreadBlockingState{ public static void main(String[] args) throws InterruptedException { Object obj= new Object(); Object obj2 = new Object(); Thread3 t3 = new Thread3(obj,obj2); Thread.sleep(1000); System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+ ",when Wait() is called & waiting for notify() to be called."); Thread4 t4 = new Thread4(obj,obj2); Thread.sleep(3000); System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+",After calling Wait() & waiting for monitor of obj2."); System.out.println("nm:"+t4.getName()+",state:"+t4.getState().toString()+",when sleep() is called."); } } class Thread3 extends Thread{ Object obj,obj2; int cnt; Thread3(Object obj,Object obj2){ this.obj = obj; this.obj2 = obj2; this.start(); } @Override public void run() { super.run(); synchronized (obj) { try { System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before Wait()."); obj.wait(); System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After Wait()."); synchronized (obj2) { cnt++; } } catch (InterruptedException e) { e.printStackTrace(); } } } } class Thread4 extends Thread{ Object obj,obj2; Thread4(Object obj,Object obj2){ this.obj = obj; this.obj2 = obj2; this.start(); } @Override public void run() { super.run(); synchronized (obj) { System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before notify()."); obj.notify(); System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After notify()."); } synchronized (obj2) { try { Thread.sleep(15000); } catch (InterruptedException e) { e.printStackTrace(); } } } }