1. 线程的生命周期
线程的整个生命周期中有六个状态,分别是:
- NEW(新创建)
- RUNNABLE(可运行)
- BLOCKED(被阻塞)
- WAITING(等待)
- TIMED_WAITTING(计时等待)
- TERMINATED(被终止)
这些状态可以通过Thread.getState()方法获取。
NEW
此状态下,线程Thread对象被实例化,但是还没有调用start()方法开始运行。
RUNNABLE
此状态下,线程可能处于就绪执行状态(一切准备就绪,就等cpu调度了)也可能处于正在运行状态。处于NEW状态下的线程调用start()方法后可进入RUNNABLE状态,处于等待、计时等待、被阻塞状态下的线程被唤醒或获取synchronized锁后可进入RUNNABLE状态。
BLOCKED
此状态下的线程是在等待获取synchronized锁,一旦获取到锁后就会进入RUNNABLE状态
WAITING
此状态下的线程是处于RUNNABLE线程调用了一些使线程阻塞等待的方法造成的,如wait、join等方法。此状态下的线程如果不被唤醒会一直处于等待状态,被唤醒的话就会进入RUNNABLE状态。
TIMED_WAITING
此状态与WAITING状态很像,只不过WAITING状态不被唤醒会一直等待而TIMED_WAITING会有一个时间限制,超过这个时间限制后还不会被唤醒就会自己强制唤醒。进入这个状态需要处于RUNNABLE状态的线程调用带时间参数的等待方法。
TERMINATED
当线程执行结束后就会进入这个状态。
代码演示线程的各个状态
- 主干状态
public class Demo4 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()){
}
});
System.out.println("t运行之前:" + t.getState());
t.start();
Thread.sleep(100);
System.out.println("t运行中:" + t.getState());
t.interrupt();
Thread.sleep(100);
System.out.println("t被中断后结束线程:" + t.getState());
}
}
执行结果:
2. 枝干状态
public class Demo5 {
static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
synchronized (lock){
while (!Thread.currentThread().isInterrupted()){
}
try {
Thread.currentThread().interrupted();
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "线程1");
Thread t2 = new Thread(() -> {
synchronized (lock){
while (!Thread.currentThread().isInterrupted()){
}
lock.notify();
}
}, "线程2");
t1.start();
Thread.sleep(100);
t2.start();
System.out.println("线程1正在执行,线程2在阻塞等待获取synchronized锁");
System.out.println(t1.getName() + " " + t1.getState());
System.out.println(t2.getName() + " " + t2.getState());
System.out.println("----------------------------------------------------");
t1.interrupt();
Thread.sleep(100);
System.out.println("使线程1跳出循环执行wait方法进入等待状态释放锁,线程2可获取锁");
System.out.println(t1.getName() + " " + t1.getState());
System.out.println(t2.getName() + " " + t2.getState());
System.out.println("----------------------------------------------------");
t2.interrupt();
//Thread.sleep(100);
System.out.println("使线程2跳出循环执行notify方法唤醒线程1,线程1被唤醒处于阻塞状态直到线程2执行完获取锁后开始继续执行,然后结束");
Thread.sleep(100);
System.out.println(t1.getName() + " " + t1.getState());
System.out.println(t2.getName() + " " + t2.getState());
}
}