關於Java線程狀態

線程狀態說明


線程狀態定義在Thread.State枚舉中,以下內容取自Thread.java源碼

NEW:

  線程尚未開始

  A thread that has not yet started is in this state. 

RUNNABLE:

  線程可運行,但可能未分配到處理器

  A thread executing in the Java virtual machine is in this state. 

BLOCKED:

  線程等待monitor鎖

  A thread that is blocked waiting for a monitor lock is in this state. 

WAITING:

  線程無限等待另一個線程執行特定的行動

  A thread that is waiting indefinitely for another thread to perform a particular action is in this state. 

TIMED_WAITING:

  線程等待另一個線程執行特定的行動,但最多等待指定的時間

  A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. 

TERMINATED:

 線程已退出

 A thread that has exited is in this state. 


如何進入BLOCKED、WAITING和TIMED_WAITING狀態


BLOCKED:

A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.


處於BLOCKED的線程正在等待monitor鎖進入synchronized塊或synchronized方法,或者是在調用了Object.wait後再次進入synchronized塊或synchronized方法。


WAITTING:

A thread is in the waiting state due to calling one of the following methods:

Object.wait with no timeout

Thread.join with no timeout

LockSupport.park


調用了以下方法的線程進入WAITTING狀態

不帶超時的Object.wait

不帶超時的Thread.join

LockSupport.park


TIMED_WAITING:

A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time.

Thread.sleep

Object.wait with timeout

Thread.join with timeout

LockSupport.parkNanos

LockSupport.parkUntil


調用了以下方法的線程進入TIMED_WAITING狀態

Thread.sleep

帶超時的Object.wait

帶超時的Thread.join

LockSupport.parkNanos

LockSupport.parkUntil


關於BLOCKED和WAITING的區別

BLOCKED狀態是等待monitor鎖,鎖是否可用是由JVM通知。而WAITTING狀態下,是否可以繼續由其他線程通知。


參考兩篇文章:


Thread.State in Java? BLOCKED vs WAITING

http://blog.csdn.net/teaey/article/details/20059129


What is Thread.State in Java? What's it used for?


Thread.State - This is a static nested class (Read more about nested classes in the article - Nested Classes & Inner Classes in Java >>) of the Thread class. This is one of the additions of Java 5 and this class actually inherits the abstract class Enum which is the common base class of all Java language enumeration types i.e., Thread.State is actually is actually an enumeration type.


Thread.State enumeration contains the possible states of a Java thread in the underlying JVM. These states are different from the Operating System thread states. The possible values of the Thread.State are:-

NEW - this state represents a new thread which is not yet started.

RUNNABLE - this state represents a thread which is executing in the underlying JVM. Here executing in JVM doesn't mean that the thread is always executing in the OS as well - it may wait for a resource from the Operating system like the processor while being in this state.

BLOCKED - this state represents a thread which has been blocked and is waiting for a moniotor to enter/re-enter a synchronized block/method. A thread gets into this state after calling Object.wait method.

WAITING - this state represnts a thread in the waiting state and this wait is over only when some other thread performs some appropriate action. A thread can get into this state either by calling - Object.wait (without timeout), Thread.join (without timeout), or LockSupport.park methods.

TIMED_WAITING - this state represents a thread which is required to wait at max for a specified time limit. A thread can get into this state by calling either of these methods:Thread.sleep, Object.wait (with timeout specified), Thread.join (with timeout specified), LockSupport.parkNanos, LockSupport.parkUntil

TERMINATED - this state reprents a thread which has completed its execution either by returning from the run() method after completing the execution OR by throwing an exception which propagated from the run() method and hence caused the termination of the thread.


Difference between BLOCKED state and WAITING / TIMED_WAITING states?


When a thread calls Object.wait method, it releases all the acquired monitors and is put into WAITING (or TIMED_WAITING if we call the timeout versions of the waitmethod) state. Now when the thread is notified either by notify() or by notifyAll() call on the same object then the waiting state of the thread ends and the thread starts attempting to regain all the monitors which it had acquired at the time of wait call. At one time there may be several threads trying to regain (or maybe gain for the first time) their monitors. If more than one threads attempt to acquire the monitor of a particular object then only one thread (selected by the JVM scheduler) is granted the monitor and all other threads are put into BLOCKED state. Got the difference?


BLOCKED和WAITING/TIMED_WAITING的區別

大意是:當一個線程調用Object.wait,它將釋放它已經獲取的monitor鎖,然後進入WAITING或者TIMED_WAITING狀態。如果現在該線程收到其他線程在此monitor鎖上的notify或者notifyAll通知,那麼該線程將結束等待狀態,並且重新嘗試獲取在調用wait時已獲取的monitor鎖,此時可能還有其他線程重新或者第一次獲取它們各自的monitor鎖,如果超過一個線程獲取同一個monitor鎖,那麼只有一個線程可以獲取到,其他線程將進入BLOCKED狀態。


Difference between WAITING and TIMED_WAITING states?


The difference is quite obvious between the two. A thread in a TIMED_WAITING state will wait at max for the specified timeout period whereas a thread in the WAITING state keeps waiting for an indefinite period of time. For example, if a thread has calledObject.wait method to put itself into WAITING state then it'll keep waiting until the thread is interrupted either by notify() method (OR by notifyAll() method) call on the same object by another thread. Similarly, if a thread has put itself into WAITINGstate by calling Thread.join method then it'll keep waiting until the specified thread terminates.


We can easily figure out that a thread in a WAITING state will always be dependent on an action performed by some other thread whereas a thread in TIMED_WAITING is not completely dependent on an action performed by some other thread as in this case the wait ends automatically after the completion of the timeout period.


Blocked vs Waiting Thread

http://www.coderanch.com/t/425685/threads/java/Blocked-Waiting-Thread


Alain Dickson問:

Hi Ranches, need your help to clear a point, 


Is there a difference in Thread's state when it encouters following two situations. I have question about Blocked state. 


Here is how I understand the two states. 

1.(WAITING). The thread enters synchronized block and calls wait() on the object whos lock it already have and waits till some other thread notify it. 


2(BLOCKED). The Thread makes a calls to synchronized method whos lock is already acquired by some other thread and gets blocked. 


Question : Once a thread is blocked, does it wait quietly for someone Or some event to tell him that the lock is available(just like wait/notify) OR it keeps on trying it until it gets lock. 


Many thanks, 

Alain 


提問者對這兩種狀態的理解是

1. WAITING:線程已經在synchronized方法中,並且調用了已經持有鎖的wait()方法,等待其他線程notify它

2. BLOCKED:線程調用了已被其他線程獲取了鎖的synchronized方法

提問者想問的問題是

如果線程在BLOCKED狀態,線程是一直重試獲取鎖(類似忙等),還是等待某個線程或事件通知它鎖可用了(類似於wait/notify)?


Mike Simmons的回答:

It will keep trying until it acquires the lock. 


Well, we could also say that it waits quietly for the JVM to tell it that the lock is available. It's similar to wait/notify, but you, the programmer, don't have to do anything. The JVM will do it for you.


回答的大意是:

線程等待JVM通知它鎖可用,類似wait/notify,但調用者無需關心


針對Mike的回答“we could also say that it waits quietly for the JVM to tell it that the lock is available. It's similar to wait/notify”,Alain Dickson又問:

well, can we say for sure that the Thread which is blocked, waits until the lock becomes available 

And that: 

1. It does not wake up in-between to check if the lock is available 

2. When the lock becomes available, Which notification JVM uses notify() OR notifyAll() 


Thanks, 

Alain


大意是:

是不是我們可以肯定的說BLOCKED線程將等待,直到鎖可用,並且

1. 線程不會在中間醒來檢查是否鎖可用

2. 當鎖可用時,JVM使用notify或者notifyAll通知


Mike Simmons的回答:

針對第一個問題:1. It does not wake up in-between to check if the lock is available

For sure? Probably not - I think the exact mechanism is implementation-dependent. 


Note that I should not have said "wait" above, since in thread discussions that has a specific meaning which does not apply here. We can say that the thread, in general, does nothing until the lock is acquired. I suppose it's possible that in some implementations, threads might occasionally "wake up" and check their status. But whatever they do, you can assume it's something reasonably efficient. The threads do not, for example, spend all their time in loops, checking and rechecking their status. That would be a waste of resources, similar to a "busy wait". 


When you asked if a thread "keeps on trying until it gets the lock", my concern was that you might think the thread is wasting resources by repeatedly waking up and asking if the lock is available yet. In general, no, it doesn't. It's possible that some implementations may do this occasionally. But I wouldn't worry about it. 


針對第一個問題,Mike認爲不能就這麼肯定,應該是實現相關的。Mike指出提問者這樣問是否是考慮重複喚醒檢查的資源浪費,並認爲有些實現中,BLOCKED的線程有可能會間斷醒來檢查鎖是否可用,但肯定不會花費所有的時間去檢查,這一點無需過分擔心。


針對第二個問題:2. When the lock becomes available, Which notification JVM uses notify() OR notifyAll()


Neither of these. I said that the JVM does something like wait/notify - but it doesn't actually use wait(), notify(), or notifyAll(). 


However, I would guess that what it does is probably more like notify() than notifyAll(). There's no good reason to bother all the threads that are trying to acquire a lock. Better to pick just one, give it the lock, and tell it to run.


針對第二個問題,Mike認爲使用的是類似notify或者notifyAll的機制,但並非notify或者notifyAll。而且Mike猜想更偏向於使用類似notify,畢竟沒有必要通知所有的線程來獲取鎖。


中間有一個叫Chris Hurst的插話:

Adaptive locking was supposed to come in with Mustang and allow java to make an educated guess as to if spinning or suspension of the thread is more efficient in a blocked scenario.

大意是:應該引入自適應的鎖,允許Java合理的猜測是自旋還是掛起。


接着提問者提出了他真正想問的問題:

Alain Dickson:

Thanks Mike, 

Though from the discussion it makes sense both sychronized method calls and wait/notify are similar systems in terms of blocking thread and make it wait, but I would like to explicitly ask that: I have a situation where the design suggests to use wait/notify but I am thinking of redesigning it into synchronized method calls where (behaviour of wait/notify) is done by JVM not by program calling wait and notify explicity, which is prone to errors as compared to calls to synchronized methods. If the design allows, will synchronized methods give similar performance as wiat/notify where I know no thread will wake up until I call notify/notifyAll? 


Thanks, 

Alain


提問者真正想問的是,既然synchronized也是類似notify機制,那麼當前有一種設計,原來建議使用wait和notify,但是因爲這種方法容易出錯,他想使用synchronize的重新設計,性能是否和wait/notify一樣


Mike Simmons:

That's an interesting idea. Yes, I would expect that both systems would probably give similar performance. If one is faster, I don't know which it would be - could be either. Probably the performance will be close enough either way that it doesn't matter, and your decision will be based on other considerations.


Mike的回答是:

不能確認哪種的性能更好,可能兩種的性能非常接近。


Alain Dickson感謝回答者Mike:

Thanks for your valueable openion Mike. 


Regards, 

Alain


又有另外一位回答者Steve Luke:

A wait/notify system usually indicates that one thread can do some work concurrently with another, but has to specifically wait for the other thread to reach a certain point before it can proceed (say a consumer which can work on data, but must wait for the producer to make the data available before getting the next piece). Since you don't have control over thread scheduling the only thing you can do is call wait() to force the consumer to wait until the producer notify()s it of completion. 


Without wait/notify (or the Condition.await()/signal() from the concurrent api) you can't really get synchrony points points between different threads because you can't be sure which threads will get processor time and get the lock on the synchronized object. For example the consumer may get to a point where it has to block on a synchronized lock held by the producer. The producer releases the lock, but the thread maintains processor time, regains the lock, and keeps working. The poor consumer is still left in the blocking state, never having the chance to gain the synchronizing lock. 


So if you are looking to synchronize two threads in the fashion wait()/notify() allows, I think it would be rather difficult to execute using just synchronized methods because it would be hard to make sure any blocking thread ever gets some run time when it is needed. You might want to look at some of the classes in the java.util.concurrent package to make things easier, like a BlockingQueue to pass signals through, a Semaphore to provide permissions for the consumer to run, Lock/Conditions for a different synchronized lock/conditional wait and notification scheme, or the CyclicBarrier to allow multiple threads to come together to a single synchronized point. Many other options as well. 


Steve的大意是:

因爲我們不能控制調度,如果沒有wait/notify系統,不能真正的獲取到同步點,僅僅使用synchronized方法也很難某些情況下的同步,使用一些其他的類可能會更簡單,比如BlockingQueue、Semaphore、CyclicBarrier等。


Alain Dickson感謝Steve:

Thanks Steve, 

I have achieved my solution using the cocurrent package. It is very flexible and interesing. 


regards, 

Alain




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章