
Java线程(或计算机线程)有一些状态来表示当前线程的运行信息。可以使用jsatck命令查看Java进程中的线程函数栈信息,包括Java线程状态。
在分析Java线程状态之前,我们先来看看进程、线程、协程这三个概念的区别:
对于开发伙伴来说,了解Java线程状态有助于加深对线程的理解,有助于解决线程死锁、线程阻塞等问题。
Java Thread类型的State枚举定义了以下6个线程状态,它们会在这些状态之间切换,直到线程终止,类似于状态机流程。
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* 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
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
*
* - {@link Object#wait() Object.wait} with no timeout
* - {@link #join() Thread.join} with no timeout
* - {@link LockSupport#park() LockSupport.park}
*
*
* A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called Object.wait()
* on an object is waiting for another thread to call
* Object.notify() or Object.notifyAll() on
* that object. A thread that has called Thread.join()
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
*
* - {@link #sleep Thread.sleep}
* - {@link Object#wait(long) Object.wait} with timeout
* - {@link #join(long) Thread.join} with timeout
* - {@link LockSupport#parkNanos LockSupport.parkNanos}
* - {@link LockSupport#parkUntil LockSupport.parkUntil}
*
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
复制代码
这些Java线程状态图如下所示:
请注意,处于 RUNNABLE 状态的线程不一定是 RUNNING。有可能CPU还在执行其他线程而没有调度线程。
我们知道Java层面对线程状态的几种定义pthread_join 如何看出是否是主线程,那么底层的Java/JDK是基于什么机制来实现线程管理的呢?我们写一个例子Demo来分析:
@SuppressWarnings("all")
public class MainDemo {
private static Object obj1 = new Object();
private static Lock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
LockSupport.park();
}
}, "t1").start();
new Thread(new Runnable() {
@Override
public void run() {
LockSupport.park(TimeUnit.DAYS.toNanos(1));
}
}, "t2").start();
lock.lock();
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
System.out.println("zzz222");
}
}, "t3").start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t4").start();
synchronized (obj1) {
new Thread(new Runnable() {
@Override
public void run() {
synchronized (obj1) {
System.out.println("zzz");
}
}
}, "t5").start();
Thread.sleep(1000000000);
}
}
}
复制代码
上面的代码启动了5个名为t1、t2到t5的子线程,其中t1执行LockSupport.park()阻塞,t2执行LockSupport.park(long)阻塞pthread_join 如何看出是否是主线程,t3执行lock.lock()阻塞,t4执行Thread.sleep()阻塞,t5执行synchronized(obj)阻塞。
可以通过jstack命令查看Java线程栈,如下图:
但是它在JDK和系统级别看不到线程堆栈。这时候可以通过pstack命令查看,如下图:
那么Java线程栈和系统层线程栈是怎么关联的呢?这时可以将Java线程栈中的nid(十六进制)与系统层线程栈中的LWP是否相等相关联。比如t1线程的线程栈如下:
通过分析t1-t5线程栈,这些线程都处于TIMED_WAITING或者WAITING状态,它们的JDK级别已经达到了pthread_cond_wait或者pthread_cond_timedwait方法,这些都是系统层pthread库中的方法,对于那些学过Linux C的同学肯定不会陌生。有兴趣的同学可以按照上面的命令查看所有线程的整个线程栈信息。
请登录后发表评论
注册
社交帐号登录