Java之线程状态浅析

线程是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,创建线程后,线程的状态为:%s\n", myThread.getName(), myThread.getState());
        myThread.start();
        System.out.printf("线程:%s,调用start()方法后,线程的状态为:%s\n", myThread.getName(), myThread.getState());
        // 休眠50毫秒,等待MyThread线程执行完
        Thread.sleep(50);
        System.out.printf("线程:%s,执行完成后,线程的状态为:%s\n", 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的状态为:%s\n", threadA.getState());
        System.out.printf("线程B的状态为:%s\n", 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线程的状态为:%s\n", threadA.getState());
        System.out.printf("线程B线程的状态为:%s\n", 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状态的线程则不去竞争锁,需要等待被动通知、或者自己定的闹钟(等待时间)到了、再去竞争锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值