当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,有几种状态呢?在API中 这个枚举中给出了六种线程状态:
这里先列出各个线程状态发生的条件,下面将会对每种状态进行详细解析:
NEW和TERMINATED状态
new状态:线程刚被创建,但是并未启动。还没调用start方法。
Terminated(被终止)状态:因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。
测试创建线程,启动线程,线程运行完毕。处于这两个状态的线程在堆栈不会出现在堆栈信息里面。
public static void testNewAndTerminatedState() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Over Run.");
}
});
System.out.println("State " + thread.getState() + ".");
thread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("State " + thread.getState() + ".");
}
运行结果:
State NEW.
Over Run.
State TERMINATED.
Runnable(可运行)状态
线程可以在java虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操作系统处理器。
public static void testStateRunnable() {
IOThread simpleThread = new IOThread("IOThread");
simpleThread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main thread check the state is " + simpleThread.getState() + "."); // RUNNABLE
}
static class IOThread extends Thread {
public IOThread(String name) {
super(name);
}
@Override
public void run() {
System.out.println("In run method, state is " + getState() + "."); // RUNNABLE
Socket socket = new Socket();
try {
System.out.println("Try to connect socket address which not exist...");
socket.connect(new InetSocketAddress(
InetAddress.getByAddress(new byte[] { (byte) 192, (byte) 168, 1, 14 }), 5678));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果:
In run method, state is RUNNABLE.
Try to connect socket address which not exist...
Main thread check the state is RUNNABLE.
主要是测试在进入run方法之后线程的状态,以及在等待IO的时候,线程的状态。
Waiting(无限等待)
Wating状态在API中介绍为:一个正在无限期等待另一个线程执行一个特别的(唤醒)动作的线程处于这一状态。
那么我们之前遇到过这种状态吗?答案是并没有,但并不妨碍我们进行一个简单深入的了解。
/**
* 线程调用wait方法,状态变成WAITING。
*/
public static void testStateWatingByWait() {
Object lock = new Object();
WaitingThread waitingThread = new WaitingThread("WaitingThread", lock);
waitingThread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main thread check the state is " + waitingThread.getState() + "."); // WAITING
}
static class WaitingThread extends Thread {
private int timeout = 0;
private Object lock;
public WaitingThread(String name, Object lock) {
this(name, lock, 0);
}
public WaitingThread(String name, Object lock, int timeout) {
super(name);
this.timeout = timeout;
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
if (timeout == 0) {
try {
System.out.println("Try to wait.");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
System.out.println("Try to wait in " + timeout + ".");
lock.wait(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Over thread.");
}
}
运行结果:
Try to wait.
Main thread check the state is WAITING.
Timed Waiting(计时等待)
同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。这一状态将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有Thread.sleep 、Object.wait。
package java06;
public class test02 extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
if ((i) % 10 == 0) {
System.out.println("‐‐‐‐‐‐‐" + i);
}
System.out.print(i);
try {
Thread.sleep(1000); System.out.print(" 线程睡眠1秒!\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new test02().start();
}
}
1.进入 TIMED_WAITING 状态的一种常见情形是调用的 sleep 方法,单独的线程也可以调用,不一定非要有协作关系。
2.为了让其他线程有机会执行,可以将Thread.sleep()的调用放线程run()之内。这样才能保证该线程执行过程中会睡眠。
3.sleep与锁无关,线程睡眠到期自动苏醒,并返回到Runnable(可运行)状态。
Blocked(锁阻塞)
当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态。
所以我们模拟两个线程抢锁,当一个线程抢到锁之后进入sleep,sleep状态下不会释放锁,所以另外一个线程被阻塞。从堆栈信息可以看到,locked和waiting to lock都是同一个对象。
public static void testBlockedState() {
Object lock = new Object();
SleepThread t1 = new SleepThread("t1", lock);
SleepThread t2 = new SleepThread("t2", lock);
t1.start();
t2.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread t1's state " + t1.getState());
System.out.println("Thread t2's state " + t2.getState());
}
static class SleepThread extends Thread {
private String name;
private Object lock;
public SleepThread(String name, Object lock) {
super(name);
this.name = name;
this.lock = lock;
}
@Override
public void run() {
System.out.println("Thread:" + name + " in run.");
synchronized (lock) {
System.out.println("Thread:" + name + " hold the lock.");
try {
Thread.sleep(1000 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread:" + name + " return the lock.");
}
}
}
运行结果:
Thread:t2 in run.
Thread:t1 in run.
Thread:t2 hold the lock.
Thread t1's state BLOCKED
Thread t2's state TIMED_WAITING
这就是我的分享。