java was blocked_关于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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值