Java Thread BLOCKED和WAITING两种状态的区别

2024-10-29 06:58:47
推荐回答(5个)
回答(1):

一、线程5种状态

新建状态(New) 新创建了一个线程对象。

就绪状态(Runnable) 线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。

运行状态(Running) 就绪状态的线程获取了CPU,执行程序代码。

阻塞状态(Blocked) 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。

同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。

其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

二、Jstack中常见的线程状态

应用程序启动后,我们对系统运行状况的观测大部分情况下是通过运行日志。但是若某一天发现,日志中记录的行为与预想的不一致,此时需要进一步的系统监控该怎么办,Jstack是常用的排查工具,它能输出在某一个时间,Java进程中所有线程的状态,很多时候这些状态信息能给我们的排查工作带来有用的线索。 
Jstack的输出中,Java线程状态主要是以下几种:

  • RUNNABLE 线程运行中或I/O等待

  • BLOCKED 线程在等待monitor锁(synchronized关键字)

  • TIMED_WAITING 线程在等待唤醒,但设置了时限

    WAITING 线程在无限等待唤醒

    1) 让线程一直处于RUNNABLE


    public static void runnable() {
            long i = 0;
            while (true) {
                i++;
            }
        }

    2) 让线程一直处于BLOCKED


    public static void blocked() {
            final Object lock = new Object();
            new Thread() {
                public void run() {
                    synchronized (lock) {
                        System.out.println("i got lock, but don't release");
                        try {
                            Thread.sleep(1000L * 1000);
                        } catch (InterruptedException e) {
                        }
                    }
                }
            }.start();

            try { Thread.sleep(100); } catch (InterruptedException e) {}

            synchronized (lock) {
                try {
                    Thread.sleep(30 * 1000);
                } catch (InterruptedException e) {
                }
            }
        }

    主线程sleep,先让另外一个线程拿到lock,并长期持有lock(sleep会持有锁,wait不会)。此时主线程会BLOCK住等待lock被释放,此时jstack的输出可以看到main线程状态是BLOCKED。这里要注意的是只有synchronized这种方式的锁(monitor锁)才会让线程出现BLOCKED状态,等待ReentrantLock则不会。

    3) 让线程处于TIMED_WAITING状态

    public static void timedWaiting() {
            final Object lock = new Object();
            synchronized (lock) {
                try {
                    lock.wait(30 * 1000);
                } catch (InterruptedException e) {
                }
            }
        }

    4)让线程处于WAITING状态

    public static void waiting() {
            final Object lock = new Object();
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                }
            }
        }

    无超时的等待,必须等待lock.notify()或lock.notifyAll()或接收到interrupt信号才能退出等待状态。






回答(2):

当一个线程在运行,而另外一个线程在等待的时候,那后一个的线程就处于Blocked(被阻塞)状态。等开头的那个线程运行完,线程调度器将会重新选一个线程,那么后面的那个线程有可能解除阻塞状态。
当一个线程执行的时候,因为某些条件不满足,然后不得不阻塞的时候,将会进入等待队列,比如调用Object.wait.这时候,这个线程就处于waiting(等待)状态。等待的意思就是等待另外一个线程去解除它的等待状态。当另外一个线程调用Object.notifyAll()的时候,等待状态的线程就会解除等待状态。
共同点:都在等待
不同点:进入等待的地方不同

你可以看看这条问题:

https://zhidao.baidu.com/question/1885326179952509668.html

回答(3):

BLOCKED状态
线程处于BLOCKED状态的场景。
当前线程在等待一个monitor lock,比如等待执行synchronized代码块或者使用synchronized标记的方法。
在synchronized块中循环调用Object类型的wait方法,如下是样例
synchronized(this)
{
while (flag)
{
obj.wait();
}
// some other code
}
WAITING状态
线程处于WAITING状态的场景。
调用Object对象的wait方法,但没有指定超时值。
调用Thread对象的join方法,但没有指定超时值。
调用LockSupport对象的park方法。
提到WAITING状态,顺便提一下TIMED_WAITING状态的场景。
TIMED_WAITING状态
线程处于TIMED_WAITING状态的场景。
调用Thread.sleep方法。
调用Object对象的wait方法,指定超时值。
调用Thread对象的join方法,指定超时值。
调用LockSupport对象的parkNanos方法。
调用LockSupport对象的parkUntil方法。

回答(4):

1、BLOCKED 就是在等待锁,如:synchronized(lock),这个状态就是在等待使用锁的线程释放锁。拿到锁了就会继续执行。
2、WAITING就是线程主动等待,如:Thread.sleep(1000),等待时间到了就会继续执行。

回答(5):

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 bynotifyAll() 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 ofwait 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?

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.