JAVA线程的学习4(线程的生命周期)

线程的生命周期

线程有哪六种状态?

public enum State {
        /** 表示一个线程还没启用(即未调用start方法)*/
        NEW,

        /**
         * JVM中执行的线程都是处于这个状态的,但是处于这个状态不一定在JVM中执行,
         * 也就是说,只有这个状态有资格被JVM调度从而获得时间片执行。
         */
        RUNNABLE,

        /**
         * 线程在等待获取锁资源从而进入阻塞状态,
         * 在这个状态中,其一直监视锁的动态,随时准备抢占锁
         * 若获得锁资源,重新进入RUNNABLE状态
         */
        BLOCKED,

        /**
         * 当调用Object.wait、Thread.join或者LockSupport类的park方法的时候,线程进入此状态,
         * 该状态若无其他线程主动唤醒,则无期限的等待。
         * 唤醒的方法包括:Object.notify(唤醒随机一个)、Object.notifyAll(唤醒全部线程),
         * 被唤醒的线程重新进入RUNNABLE状态
         */
        WAITING,

        /**
         * 同WAITING状态,不过不同的是调用的方法加上了时间的限制,
         * 例如:Object.wait(10)、Thread.sleep(10)、Thread.join(10)、LockSupport.parkNanos(10)、LockSupport.parkUntil(10)这些方法
         * 唤醒的方法有两种:
         *     1、时间过期。
         *     2、其他线程调用了notify或者notifyAll
         *  唤醒之后同样进入RUNNABLE状态
         */
        TIMED_WAITING,

        /** 线程的终点(正常死亡或者被终止)*/
        TERMINATED;
    }

线程状态的转换过程

除了NEW和TERMINATED之外,其他的状态都是可以相互转换的,其转换过程如下图所示:
在这里插入图片描述
这里特别讲一下RUNNABLE状态,在这个状态中线程并不一定在执行程序,只有被JVM调度的线程才能获得执行的时间片,并且只有这个状态的线程才能够获得时间片,换句话说,被JVM调度并且获得时间片是只属于处于RUNNABLE状态线程的权利。
关于线程状态转换的例子,可以通过下面的代码加深理解。

public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        // 1.NEW状态
        Thread thread = new Thread(() -> {
            // 3.进行test对象锁的争夺,若抢到锁则继续执行,否则进入BLOCKED状态监控该锁,重新获得后进入RUNNABLE 
            synchronized (test) {
                try {
                    // 4.进入TIMED_WAITING状态,100ms后重新进入RUNNABLE状态争夺时间片 
                    Thread.sleep(100);
                    // 5.重新获得时间片之后,进入WAITING状态 
                    test.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 6.正常run()方法执行完毕后线程结束,进入TERMINATED 
        });
        // 2.调用start()方法,线程进入RUNNABLE状态
        thread.start();
    }
}

线程的New,Runnable,Terminated状态:

package threadcoreknowledge.sixstates;

/**
 * 描述: 展示线程的三种状态:New,Runnable,Terminated。即使是正在运行,也是Runnable状态,而不是Running。
 */
public class NewRunnableTerminated implements Runnable{

    public static void main(String[] args) {
        Thread thread = new Thread(new NewRunnableTerminated());
        //打印出new的状态
        System.out.println(thread.getState());
        thread.start();
        //打印出Runnable状态
        System.out.println(thread.getState());
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //打印出Runnable的状态,即使是正在运行,也是Runnable而不是Running。
        System.out.println(thread.getState());
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //打印出Terminated状态。
        System.out.println(thread.getState());
    }
    @Override
    public void run() {
        for (int i = 0; i < 1000 ; i++) {
            System.out.println(i);
        }
    }
}

运行结果为

E:\.jdks\corretto-1.8.0_252\bin\java.exe "-javaagent:E:\IntelliJ IDEA 2019.3.5\lib\idea_rt.jar=62646:E:\IntelliJ IDEA 2019.3.5\bin" -Dfile.encoding=UTF-8 -classpath E:\.jdks\corretto-1.8.0_252\jre\lib\charsets.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\access-bridge-64.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\cldrdata.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\dnsns.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\jaccess.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\jfxrt.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\localedata.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\nashorn.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\sunec.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\sunjce_provider.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\sunmscapi.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\sunpkcs11.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\zipfs.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\jce.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\jfxswt.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\jsse.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\management-agent.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\resources.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\rt.jar;E:\workspace\thread-study\out\production\demo01 threadcoreknowledge.sixstates.NewRunnableTerminated
NEW
RUNNABLE
0
1
...
766
RUNNABLE
767
...
999
TERMINATED

Process finished with exit code 0

线程的Blocked,Waiting,TimedWaiting状态:

package threadcoreknowledge.sixstates;

/**
 * 描述: 展示Blocked,Waiting,TimedWaiting。
 */
public class BlockedWaitingTimedWaiting implements Runnable{
    public static void main(String[] args) {
        BlockedWaitingTimedWaiting Runnable = new BlockedWaitingTimedWaiting();
        Thread thread1 = new Thread(Runnable);
        thread1.start();
        Thread thread2 = new Thread(Runnable);
        thread2.start();
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //打印出TIMED_WAITING状态,因为线程1正在执行Thread.sleep(1000);
        System.out.println(thread1.getState());
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //打印出BLOCKED状态,因为线程2想要拿到syn()的锁却拿不到。
        System.out.println(thread2.getState());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //打印出WAITING,因为线程1执行完sleep,执行wait()方法。
        System.out.println(thread1.getState());
    }
    @Override
    public void run() {
        syn();
    }
    private synchronized void syn() {
        try {
            Thread.sleep(1000);
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果为:

E:\.jdks\corretto-1.8.0_252\bin\java.exe "-javaagent:E:\IntelliJ IDEA 2019.3.5\lib\idea_rt.jar=62724:E:\IntelliJ IDEA 2019.3.5\bin" -Dfile.encoding=UTF-8 -classpath E:\.jdks\corretto-1.8.0_252\jre\lib\charsets.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\access-bridge-64.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\cldrdata.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\dnsns.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\jaccess.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\jfxrt.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\localedata.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\nashorn.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\sunec.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\sunjce_provider.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\sunmscapi.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\sunpkcs11.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\ext\zipfs.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\jce.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\jfxswt.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\jsse.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\management-agent.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\resources.jar;E:\.jdks\corretto-1.8.0_252\jre\lib\rt.jar;E:\workspace\thread-study\out\production\demo01 threadcoreknowledge.sixstates.BlockedWaitingTimedWaiting
TIMED_WAITING
BLOCKED
WAITING

阻塞状态是什么?

一般习惯而言,把Blocked(被阻塞)、Waiting(等待)、Timed_waiting(计时等待)都称为阻塞状态。而不仅仅是Blocked状态。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值