
首先我们从源码查看线程的状态定义
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:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* 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:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
NEW
即用new关键字新建一个线程,这个线程就处于新建状态。

RUNNABLE
此时线程的状态正在 Java 虚拟机中执行,但它还有可能在等待来自操作系统分配的其他资源。

BLOCKED
此时线程在等待获取monitor锁,从而进入同步方法里面。
对于这种状态,我们采用另外一种方式查看状态,就是借助jps和jstack命令。
jps
jps是jdk提供的一个查看当前java进程的小工具, 可以看做是JavaVirtual Machine Process Status Tool的缩写,用来显示当前所有java进程pid
jstack
用于打印出给定的java进程ID的Java堆栈信息
public class ThreadState implements Runnable {
@Override
public void run() {
block();
}
public static void main(String[] args) {
Runnable runnable = new ThreadState();
Thread thread = new Thread(runnable);
thread.setName("Thread");
Thread thread1 = new Thread(runnable);
thread1.setName("Thread1");
thread.start();
thread1.start();
System.out.println("thread线程:" + thread.getState());
System.out.println("thread1线程:" + thread1.getState());
}
synchronized private void block() {
try {
System.out.println("当前线程的状态:"+Thread.currentThread().getName()+"进入任务,状态为"+Thread.currentThread().getState());
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

运行结果可以看出,thread线程由于先获取到monitor锁,但是在run方法里面调用了sleep(time)方法,所以此时thread线程状态为TIMED_WAITING,同样可以得到另一个结论,线程调用sleep方法的时候,不会释放monitor锁的。thread1同样启动了,但是此时thread线程一直持有monitor锁,thread1线程在等待获取到monitor锁,此时thread1的状态即为BLOCKED。
WAITING

如果我们直接在run方法里面调用wait()方法,其实调用的是当前对象的wait()方法,运行发现抛出了IllegalMonitorStateException
我们深入源码来看一下这个异常的具体解释
/**
* Thrown to indicate that a thread has attempted to wait on an
* object's monitor or to notify other threads waiting on an object's
* monitor without owning the specified monitor.
*
* @author unascribed
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
* @see java.lang.Object#wait()
* @see java.lang.Object#wait(long)
* @see java.lang.Object#wait(long, int)
* @since JDK1.0
*/
大概意思是:这个异常表明当前线程在没有拥有monitor的情况下而试图在一个对象的monitor上等待或者去通知其他线程在一个对象的monitor下等待。一句话就是:要调用wait()方法,必须拥有一个monitor。
第一种方式:使用synchronized修饰类,然后调用类的wait()方法
public void run() {
synchronized (ThreadState.class){
try {
ThreadState.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
第二种方式:使用synchronized修饰方法,然后调用这个类的wait()方法
public class ThreadState implements Runnable {
@Override
public void run() {
doWait();
}
synchronized private void doWait() {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Runnable runnable = new ThreadState();
Thread thread = new Thread(runnable);
thread.setName("Thread");
thread.start();
}
}
public class ThreadState implements Runnable {
Object lock=new Object();
@Override
public void run() {
synchronized (lock){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Runnable runnable = new ThreadState();
Thread thread = new Thread(runnable);
thread.setName("Thread");
thread.start();
}
}

TERMINATED
线程终止状态

网友评论