JAVA中6种线程状态
位于java.lang.Thread类中有个内部枚举State,定义了Java中6种线程状态,可以通过使用Thread的getState()获取线程状态
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}
1. NEW
创建后尚未启动的线程处于这个状态
public class NewThread extends Thread{
@Override
public void run() {
System.out.println("NewThread run");
}
}
public class Main {
public static void main(String[] args) {
NewThread thread = new NewThread();
System.out.println(thread.getState());
}
}
2. RUNNABLE
处于此状态的线程可能正在运行(running),也可能正在等待系统资源(ready)
public class NewThread extends Thread{
@Override
public void run() {
System.out.println("NewThread run");
}
}
public class Main {
public static void main(String[] args) {
ExtendClass thread = new ExtendClass();
thread.start();
System.out.println(thread.getState());
}
}
3. BLOCKED
阻塞状态,当一个线程要进入synchronized语句块/方法时,如果没有获取到锁,会变成BLOCKED,或者在调用Object.wait()后,被notify()唤醒,再次进入synchronized语句块/方法时,如果没有获取到锁,会变成BLOCKED
3.1 第一种情况:enter 同步块阻塞
thread1和thread2,先让thread1占用BlockThread.block(),由于block()执行需要10s,thread2在1s后start,由于同步,没有进入block(),被堵塞住,此时输出状态为BLOCKED
public class Block {
public static synchronized void block(){
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
Block.block();
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
Block.block();
}
});
thread1.start();
try {
Thread.sleep(1000);// 保证thread1运行
} catch (InterruptedException e) {
e.printStackTrace();
}
thread2.start();
try {
Thread.sleep(1000);// 保证thread2运行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread2.getState());
}
}
3.2 第二种情况: wait后reenter同步块阻塞
thread1和thread2得到lock对象锁后都调用了wait方法,释放掉了。接着thread3得到lock对象锁后调用notifyAll后,thread1和thread2开始抢占lock,其中有一个抢到,另一个就处于阻塞状态
public class Main {
public static void main(String[] args) {
Object lock = new Object();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("thread1准备wait等待,释放lock");
lock.wait();
Thread.sleep(1000);
System.out.println("thread1拿到lock,继续下一步");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("thread2准备wait等待,释放lock");
lock.wait();
Thread.sleep(1000);
System.out.println("thread2拿到lock,继续下一步");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("thread3拿到lock,准备notify");
lock.notifyAll();
System.out.println("thread3释放lock");
}
System.out.println("thread1状态:"+thread1.getState());
System.out.println("thread2状态:"+thread2.getState());
}
});
thread1.start();
thread2.start();
try {
Thread.sleep(500);// 保证thread1 thread2运行
} catch (InterruptedException e) {
e.printStackTrace();
}
thread3.start();
}
}
4. WAITING
线程陷入无限期等待状态,使用以下三个方法会让线程处于这种状态
- Object.wait()
- Thread.join()
- LockSupport.park()
4.1 wait()
thread1进入同步代码块,获取到lock的对象锁,但是调用了lock的wait()方法,释放掉了对象锁,此时进入waiting状态,同时thread2执行,获取到lock的对象锁,调用lock的notify()方法,唤醒等待线程中任意一个,由于就1个,所以唤醒thread1
public class Main{
public static void main(String[] args) {
Object lock = new Object();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("thread1准备wait等待,释放lock");
lock.wait();
System.out.println("thread1拿到lock,继续下一步");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread1.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread1.getState());
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("thread2拿到lock,准备notify");
lock.notify();
System.out.println("thread2释放lock");
}
}
});
thread2.start();
}
}
4.2 join()
public class Main{
public static void main(String[] args) {
Thread parent = new Thread( () -> {
Thread son = new Thread(() -> {
System.out.println("子线程执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
son.start();
try {
son.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
parent.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(parent.getState());
}
}
4.3 park()
public class Main{
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
System.out.println("park执行前");
LockSupport.park();
System.out.println("park执行后");
});
thread1.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread1.getState());
LockSupport.unpark(thread1);
System.out.println("执行unpack");
}
}
5. TIMED_WAITING
限期等待状态,在一定时间之后会由系统自动唤醒
- Thread.sleep()
- Object.wait(timeout)
- Thread.join(timeout)
- LockSupport.parkNanos()
- LockSupport.parkUntil()
5.1 sleep()
public class Main{
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
try {
Thread.sleep(2 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread1.start();
System.out.println(thread1.getState());
}
}
5.2 wait(timeout)
public class Main{
public static void main(String[] args) {
Object lock = new Object();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("thread1准备wait等待,释放lock");
lock.wait(1000);
System.out.println("thread1拿到lock,继续下一步");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread1.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread1.getState());
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("thread2拿到lock,准备notify");
lock.notify();
System.out.println("thread2释放lock");
}
}
});
thread2.start();
}
}
5.3 join(timeout)
public class Main{
public static void main(String[] args) {
Thread parent = new Thread( () -> {
Thread son = new Thread(() -> {
System.out.println("子线程执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
son.start();
try {
son.join(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
parent.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(parent.getState());
}
}
5.4 parkNanos()
public class Main{
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
System.out.println("parkNanos执行前");
LockSupport.parkNanos(1000 *1000 * 1000);
System.out.println("parkNanos执行后");
});
thread1.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread1.getState());
LockSupport.unpark(thread1);
System.out.println("执行unpack");
}
}
5.5 parkUntil()
public class Main{
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
System.out.println("parkUntil执行前");
LockSupport.parkUntil(System.currentTimeMillis() + 1000);
System.out.println("parkUntil执行后");
});
thread1.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread1.getState());
LockSupport.unpark(thread1);
System.out.println("执行unpack");
}
}
6. TERMINATED
终止状态,处于此状态的线程执行完run方法
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread.getState());
}
}