Java中6种线程状态详解

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());
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aabond

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值