线程状态WAIT和线程状态BLOCKED之间有什么区别?
BLOCKED(阻塞)
在等待获取监视器锁的线程处于此状态。WAITING(等待)
无限期地等待另一个线程执行特定操作的线程处于此状态。
这并没有为我解释清楚它们之间的区别。
线程状态WAIT和线程状态BLOCKED之间有什么区别?
BLOCKED(阻塞)
在等待获取监视器锁的线程处于此状态。WAITING(等待)
无限期地等待另一个线程执行特定操作的线程处于此状态。
这并没有为我解释清楚它们之间的区别。
wait()
方法,就会进入等待状态,这被称为等待状态。 一旦一个线程到达等待状态,它将需要等待直到另一个线程在该对象上调用 notify()
或 notifyAll()
方法。notifyAll()
),或者第一个线程尚未完成工作,因此仍然被阻塞,直到获得机会。 这被称为阻塞状态。 当一个线程试图获取对象上的锁,并且某些其他线程已经持有锁时,将会发生阻塞状态。区别相对简单。
在 BLOCKED
状态下,线程即将进入一个 synchronized
块,但是另一个线程正在同一个对象上运行一个 synchronized
块。第一个线程必须等待第二个线程退出其块。
在 WAITING
状态下,线程正在等待来自另一个线程的信号。这通常通过调用 Object.wait()
或 Thread.join()
实现。线程将保持在此状态直到另一个线程调用 Object.notify()
或死亡。
Object.wait()
,但是当你使用更高级的并发构造 - 如锁、阻塞队列等时,你最终会进入 WAITING
状态... 广义地说,每当两个线程需要协调时。 - FlavioThread.State
的说明是,“……这些状态是虚拟机状态,不反映任何操作系统线程状态。” 换句话说,JVM不关心正在运行Java代码的线程、等待系统调用返回的线程或等待时间片的线程之间的区别。在JVM看来,它们都只是RUNNABLE
。 - Solomon SlowWAITING
状态切换时,需要先进入BLOCKED
状态直到获取与其等待的对象相关联的锁之后,才能继续执行。这段话可以加上一句话,指出这个过程中的细节。 - Graynotify
。但是,仅供一些人了解,他们认为notify
始终是更好的选择。如果您的应用程序可能会出现死锁类似的情况(如果发生这种情况,您的应用程序将无法按照您的意图工作),则应使用notifyAll
,以避免“错过信号”(在这里,预期的线程错过了信号,因为信号到达了其他线程而不是预期的线程)。请参见https://dev59.com/_nVD5IYBdhLWcg3wQZQg#3186336。 - user104309解读线程转储的简化视角:
一个常见的例子是使用C
编写的本地套接字监听器方法,实际上正在等待任何流量到达,所以我现在是空闲的。在这种情况下,这可以看作是一种特殊的WAIT
,因为我们实际上根本没有RUNNING
(没有CPU燃烧),但您必须使用操作系统线程转储而不是Java线程转储来查看它。
RUNNABLE
还不太对。它可能在Java运行队列中,但没有执行,也可能正在执行Java代码。它不一定要调用本地代码。 - Gray被阻塞-您的线程处于可运行的状态,试图获取对象锁。 等待-您的线程处于等待状态,等待通知信号进入可运行线程的状态。
看这个例子:
线程状态的演示。
/*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();
}
}
}
}