目录
状态总述和图解
JAVA线程总共有六种状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。
线程运行状态图解:
Copy下JDK源码,进入Thread类可以看到如下信息:
/**
* A thread state. A thread can be in one of the following states:
* <ul>
* <li>{@link #NEW}<br>
* A thread that has not yet started is in this state.
* </li>
* <li>{@link #RUNNABLE}<br>
* A thread executing in the Java virtual machine is in this state.
* </li>
* <li>{@link #BLOCKED}<br>
* A thread that is blocked waiting for a monitor lock
* is in this state.
* </li>
* <li>{@link #WAITING}<br>
* A thread that is waiting indefinitely for another thread to
* perform a particular action is in this state.
* </li>
* <li>{@link #TIMED_WAITING}<br>
* A thread that is waiting for another thread to perform an action
* for up to a specified waiting time is in this state.
* </li>
* <li>{@link #TERMINATED}<br>
* A thread that has exited is in this state.
* </li>
* </ul>
*
* <p>
* A thread can be in only one state at a given point in time.
* These states are virtual machine states which do not reflect
* any operating system thread states.
*
* @since 1.5
* @see #getState
*/
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
/**
* Thread state for a thread which has not yet started.
* 线程还没有启动
*/
NEW
NEW:新建状态,线程中的任务代码还没有开始执行,如new Mythread(),此时处于新建状态,新建状态的线程没有执行start()方法
二、线程状态——RUNNABLE
/**
* 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.
* 线程正在JVM中运行,但是也可能正在等待操作系统的其他资源,比如说处理器
*/
RUNNABLE
RUNNABLE:就绪状态,即可运行状态;当线程调用了start()方法,当前线程进入可运行状态,可运行状态并不立即执行run()方法,它还需要于其他线程争夺CPU的使用权限。
public class Mythread extends Thread {
public Mythread() {
System.out.println("线程名称:" + currentThread().getName()
+ ",构造方法中的状态:" + Thread.currentThread().getState()
+ ",线程是否存活:" + Thread.currentThread().isAlive());
}
@Override
public void run() {
System.out.println("线程名称:" + currentThread().getName()
+ ",Run方法中的状态:" + Thread.currentThread().getState()
+ ",线程是否存活:" + Thread.currentThread().isAlive());
}
public static void main(String[] args) throws InterruptedException {
Mythread mythread = new Mythread();
System.out.println("线程名称:" + mythread.getName()
+ ",实例化对象后的状态:" + mythread.getState()
+ ",线程是否存活:" + mythread.isAlive());
Thread.sleep(1000);
mythread.start();
Thread.sleep(1000);
System.out.println("线程名称:" + mythread.getName()
+ ",线程运行结束后状态:" + mythread.getState()
+ ",线程是否存活:" + mythread.isAlive());
}
}
查看执行结果:
三、线程状态——BLOCKED
/**
* 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}.
* 线程因为在等待一个监控锁,处在阻塞状态。
* 此时线程需要一个监控锁去进入一个同步代码块或者同步方法。
* 或者,在程序调用Object.wait方法后需要重新进入一个同步代码块或者同步方法。
*/
BLOCKED
BLOCKED:阻塞状态,线程获取锁失败,会加入线程等待锁的同步阻塞队列,进入阻塞状态。
四、线程状态——WAITING
/**
* 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
线程处于WAITING状态是因为调用了以下几种方法:
Objetc.wait() / Thread.join() / LockSupport.park()
此时线程正在等待另一个线程执行完特定的动作。比如线程A调用了Object.wait()方法,它需要等待另一个线程B调用Object.notify()或者Object.notifyAll()来唤醒。又如,一个线程调用了Thread.join()方法,这时候需要等待一个特定的线程结束。
WAITING:又叫条件等待状态,当线程的运行条件不满足时,通过锁的条件等待机制(调用锁对象的wait()或显示锁条件对象的await()方法)让线程进入等待状态(WAITING)。处于等待状态的线程将不会被cpu执行,除非线程的运行条件得到满足后,其可被其他线程唤醒,进入阻塞状态(Blocked)。调用不带超时的Thread.join()方法也会进入等待状态。
1、创建锁对象:
注:一般情况下,不建议用String作为锁,在此为方便只作示例
因为在JVM中具有String常量池(如果两个String具有相同的值,那么他们的地址是相同的,都保存在这个常量池中)。当以String作为锁的时候,如果值相同则,那么线程持有相同的锁。这样就造成了另外一个线程不能执行。
public class MyLock {
public static final String lock = "lock";
}
2、创建线程类和执行main()方法:
public class MyThread extends Thread {
@Override
public void run() {
synchronized (MyLock.lock){
try {
MyLock.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
myThread.start();
Thread.sleep(1000);
System.out.println("线程名称:" + myThread.getName()
+ ",线程运行状态:" + myThread.getState()
+ ",线程是否存活:" + myThread.isAlive());
}
}
执行结果:
五、线程状态——TIME_WATING(限时等待)
/**
* 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
TIME_WATING:此状态下线程等待具有一个确定的时间。线程处于此种状态,是因为调用了以下几种方法之一,并指定了一个明确的等待时间。
- Thread.sleep()
- Object.wait() with timeout
- Thread.join() with timeout
- LockSupport.parkNanos()
- LockSupport.parkUntil()
线程执行了诸如Thread.sleep()或带有时间设定的Thread.join()、Object.wait()等方法时的等待状态,超过设定的等待时间后,等待线程会自动唤醒,进入阻塞状态(Blocked)或者可运行状态(RUNNABLE)。
测试代码:
public class Mythread extends Thread {
@Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Mythread mythread = new Mythread();
mythread.start();
Thread.sleep(1000);
// 打印下边语句的时候,线程还在睡眠当中
System.out.println("线程名称:" + mythread.getName()
+ ",线程运行结束后状态:" + mythread.getState()
+ ",线程是否存活:" + mythread.isAlive());
}
}
执行结果:
六、线程状态——TERMINATED
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED
TERMINATED状态下,线程已经执行完成。
BLOCKED——等待锁测试(待验证)
BLOCKED:阻塞状态,线程获取锁失败,会加入线程等待锁的同步阻塞队列,进入阻塞状态。该阻塞线程在获取锁后,会进入可运行状态(RUNNABLE),这里需要记住,线程是不能直接由非就绪状态进入运行状态的。
1、创建带同步方法的MyService类:
public class MyService {
public synchronized void serviceMethod() {
try {
System.out.println(Thread.currentThread().getName()+":执行serviceMethod方法中...");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2、创建线程A和线程B:
线程A:
public class MyThreadA extends Thread {
private MyService myService;
public MyThreadA(MyService myService){
super();
this.myService = myService;
}
@Override
public void run() {
myService.serviceMethod();
}
}
线程B:
public class MyThreadB extends Thread {
private MyService myService;
public MyThreadB(MyService myService){
super();
this.myService = myService;
}
@Override
public void run() {
myService.serviceMethod();
}
}
3、执行方法:
public static void main(String[] args) throws InterruptedException {
MyService myService = new MyService();
MyThreadA mythreadA = new MyThreadA(myService);
mythreadA.setName("线程A");
mythreadA.start();
MyThreadB mythreadB = new MyThreadB(myService);
mythreadB.setName("线程B");
mythreadB.start();
// 打印线程B的状态
System.out.println("线程名称:" + mythreadB.getName()
+ ",线程运行状态:" + mythreadB.getState()
+ ",线程是否存活:" + mythreadB.isAlive());
}
执行结果:
注:此处运行是处于就绪状态(RUNNABLE),sleep()方法不会释放锁,在只有一个对象锁的情况下,线程B是不会拿到锁的,所以这个状态应该是阻塞状态。
isAlive()方法
isAlive()方法是测试线程是否处于活动状态。从以上线程运行状况和结果可以得知,只有当线程在新建(NEW)和销毁(TERMINATED)状态时,线程的存活状态为false,其他时候线程始终处于活动状态。