概述
线程是JVM执行任务的最小单元,java中线程的状态一共有NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED六种状态,对应Tread类中的内部State枚举类。
public static enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
private State() {
}
}
NEW和TERMINATED:当创建一个线程后,还没有调用start方法时,线程处于NEW状态,线程执行完成,退出后变为TERMINATED终止状态。
RUNNABLE:调用start方法后,线程进入RUNNABLE可运行状态。
public class ThreadStateTest {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
System.out.printf("线程:%s,创建线程后,线程的状态为:%sn", myThread.getName(), myThread.getState());
myThread.start();
System.out.printf("线程:%s,调用start()方法后,线程的状态为:%sn", myThread.getName(), myThread.getState());
// 休眠50毫秒,等待MyThread线程执行完
Thread.sleep(50);
System.out.printf("线程:%s,执行完成后,线程的状态为:%sn", myThread.getName(), myThread.getState());
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.printf("%s线程运行n", Thread.currentThread().getName());
}
}
运行结果
验证了创建线程后状态为NEW,调用start()方法后状态为RUNNABLE,然后新建线程中run方法执行,main主线程休眠50毫秒,新建线程执行完成后状态为TERMINATED。
BLOCKED:在运行态中的线程进入 synchronized 同步块或者同步方法时,如果获取锁失败,则会进入到 BLOCKED 状态。当获取到锁后,会从 BLOCKED 状态恢复到就绪状态。
public class ThreadBlockedStateTest {
public static void main(String[] args) {
Thread threadA = new Thread(() -> method01(), "A-Thread");
Thread threadB = new Thread(() -> method01(), "B-Thread");
threadA.start();
threadB.start();
System.out.printf("线程A的状态为:%sn", threadA.getState());
System.out.printf("线程B的状态为:%sn", threadB.getState());
}
/**
* 停顿10毫秒、模拟方法执行耗时
*/
public static synchronized void method01() {
System.out.printf("[%s]:开始执行主线程的方法n", Thread.currentThread().getName());
try {
Thread.sleep(10);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("[%s]:主线程的方法执行完毕n", Thread.currentThread().getName());
}
}
运行结果
线程A优先获得了锁,状态为RUNNABLE,线程B状态为BLOCKED。
WAITING和TIMED_WAITING:运行中的线程还会进入等待状态,这两个等待一个是有超时时间的等待,另外一个是无超时的等待。这两种等待都可以通过 notify 或 unpark 结束等待状态并恢复到就绪状态。
public class ThreadWaitingStateTest {
public static void main(String[] args) throws InterruptedException {
Ticket ticket = new Ticket();
Thread threadA = new Thread(() -> {
synchronized (ticket) {
while (ticket.getNum() == 0) {
try {
ticket.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
ticket.buy();
}
}, "线程A");
Thread threadB = new Thread(() -> {
synchronized (ticket) {
while (ticket.getNum() == 0) {
try {
ticket.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
ticket.buy();
}
}, "线程B");
threadA.start();
threadB.start();
// 确保A和B线程都运行起来
Thread.sleep(10);
System.out.printf("线程A线程的状态为:%sn", threadA.getState());
System.out.printf("线程B线程的状态为:%sn", threadA.getState());
Thread employeeThread = new Thread(() -> {
synchronized (ticket) {
if (ticket.getNum() == 0) {
ticket.addTicket();
ticket.notifyAll();
}
}
}, "补票员");
employeeThread.start();
}
}
class Ticket {
private int num = 0;
public int getNum() {
return num;
}
public void addTicket() {
try {
Thread.sleep(2_000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
this.num += 2;
}
/**
* 停顿10毫秒、模拟方法执行耗时
*/
public void buy() {
System.out.printf("[%s]:购买了一张票n", Thread.currentThread().getName());
System.out.printf("[%s]:退出售票厅n", Thread.currentThread().getName());
}
}
运行结果
BLOCKED状态的线程还是在竞争锁的,一旦cpu有时间竞争到了就会执行。
WAITING状态的线程则不去竞争锁,需要等待被动通知、或者自己定的闹钟(等待时间)到了、再去竞争锁。
最后
以上就是风趣帽子为你收集整理的Java之线程状态浅析的全部内容,希望文章能够帮你解决Java之线程状态浅析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复