WAIT和BLOCKED线程状态之间的区别
线程状态WAIT和线程状态BLOCKED有什么区别?
Thread.State文档 :
阻止
阻塞等待监视器locking的线程处于此状态。等候
无限期地等待另一个线程执行特定动作的线程处于这种状态
没有向我解释这个区别。
一旦线程调用Object的wait()
,线程就会进入等待状态。 这叫做等待状态。 一旦一个线程达到等待状态,它将需要等待对象上的其他线程notify()
或notifyAll()
。
一旦这个线程被通知,它将不能运行。 也可能是其他线程也被通知(使用notifyAll()
),或者第一个线程还没有完成他的工作,所以它仍然被阻塞,直到有机会。 这被称为阻塞状态。
一旦其他线程已经离开,并且它的线程有机会,它将移动到Runnable状态,之后它将根据JVM线程机制进行工作并移动到运行状态。
差别是比较简单的。
在BLOCKED
状态下,一个线程即将进入一个synchronized
块,但是在同一个对象的synchronized
块内部还有另一个线程正在运行。 第一个线程必须等待第二个线程退出它的块。
在WAITING
状态下,一个线程正在等待来自另一个线程的信号。 这通常通过调用Object.wait()
或Thread.join()
。 线程将保持这种状态,直到另一个线程调用Object.notify()
或死亡。
解释线程转储的简单透视图:
等待 – 我正在等待一些工作,所以我现在闲着。
封锁 – 我正忙于完成工作,但另一条线路正在阻碍我,所以我现在闲置。
RUNNABLE …(Native Method) – 我调用了一些本地代码(尚未完成),所以就JVM而言,你是RUNNABLE的,它不能提供任何进一步的信息。 一个常见的例子是一个用C语言编写的本地套接字监听器方法,它实际上是等待任何stream量到达,所以我现在闲置。 在这种情况下,这可以被看作是一种特殊的WAIT,因为我们实际上并不是真正运行(没有CPU烧录),但是您必须使用操作系统线程转储而不是Java线程转储来查看它。
被阻塞 – 您的线程处于线程生命周期的可运行状态,并尝试获取对象locking。 等待 – 线程处于线程生命周期的等待状态并等待通知信号进入线程的运行状态。
阻塞和等待状态之间的重要区别是对调度程序的影响。 处于阻塞状态的线程是争用锁的等待集的一部分; 那个线程仍然算作调度器需要服务的东西,可能会影响它决定给予多less时间来运行线程。
一旦线程处于等待状态,系统所承受的压力就会降到最低,调度程序不必担心。 它一直处于hibernate状态,直到收到通知。 除了保持一个操作系统线程被占用的事实之外,它完全没有作用。
这就是为什么使用notifyAll不太理想的原因,它会导致一堆以前愉快地hibernate的线程,使得系统中没有任何负载被唤醒,其中大多数会阻塞,直到他们能够获得锁,find它们的状态等待是不正确的,回去等待。 最好只通知那些有进展机会的线程。
看到这个例子:
线程状态的演示。
/*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(); } } } }