多线程 (四) Java 线程的几种状态

???点进来你就是我的人了
博主主页:???戳一戳,欢迎大佬指点!

人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习!

欢迎志同道合的朋友一起加油喔???
目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个?嘿嘿
谢谢你这么帅气美丽还给我点赞!比个心


目录

1.线程的状态

2.线程的生命周期

 3.线程的状态演示

3.1 NEW和TERMINATED

 3.3 WAITING

 3.4 BLOCKED



1.线程的状态

线程共有6种状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。分别对应于:新建、运行、阻塞、等待、带超时的等待、终止。

1)新建状态(New)
当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

2)就绪状态(Runnable)
当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

3)运行状态(Running)
当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

4)阻塞状态(Blocked)
处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

1、等待阻塞
运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

2、同步阻塞
线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

3、其他阻塞
通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5)死亡状态(Dead)
线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

用一张图来将其概括的话会更容易记忆:

2.线程的生命周期

 3.线程的状态演示

3.1 NEW和TERMINATED

在这个程序之中,我们首先创建了一个Thread对象,然后运用lambda表达式来实现run方法.在run方法之中什么都不做,只是循环.然后打印在t.start之前和t线程运行完之后,线程所处的状态.其中t,join是为了让main线程等待t线程执行完毕后再继续执行,否则main方法可能会先执行完毕.

public class ThreadDemo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
           for(int i = 0;i<1000000;i++){
 
           }
        });
        //t调用start之前,是NEW状态.
        System.out.println("线程执行之前:"+t.getState());
        t.start();
        t.join();
        //线程执行完毕之后,就是TERMINATED状态.
        System.out.println("线程执行之后:"+t.getState());
    }
}

 3.2 RUNNABLE和TIME_WAITING

下面代码我们可以看见RUNNABLE,主要是因为我们当前线程的run方法里面没有sleep,join之类的方法,否则在后续打印中就不一定是RUNNABLE状态了.

public class ThreadDemo2 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
           for(int i = 0;i<1000;i++){
 
           }
        });
        System.out.println("线程执行之前:"+t.getState());
        t.start();
        //线程处于可执行状态
        System.out.println("线程运行中:"+t.getState());
        t.join();
        System.out.println("线程运行完:"+t.getState());
    }
}

 3.3 WAITING

我们使用wait方法可以使线程出现WAITING状态.在下面代码中,我们使t2线程等待t1线程,当t1线程执行完毕之后,t2线程才开始执行.

public class ThreadDemo3 {
    public static void main(String[] args) throws InterruptedException {
        Object obj = new Object();
        Thread t1 = new Thread(()->{
            for(int i = 0;i<1000;i++){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (obj){
                obj.notify();
            }
            System.out.println("线程t1执行完毕!");
        });
        Thread t2 = new Thread(()->{
            synchronized (obj){
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t1.start();
        //此时t2没有调用start方法,是NEW
        System.out.println("t2 start之前:"+t2.getState());
        t2.start();
        Thread.sleep(10);
        //此时线程t2等待线程t1执行完毕,应该是WAITING状态
        System.out.println("t2 wait中:"+t2.getState());
        t1.join();
        t2.join();
        //此时t2执行完毕,TERMINATED
        System.out.println("t2执行完成:"+t2.getState());
    }
}

 3.4 BLOCKED

BLOCKED是阻塞状态,死锁就可能会出现这种状态.在下面代码中,我们创建了两个线程,一个t1,一个t2,我们先让t1获取obj1,然后再获取obj2.然后让t2获取obj2,再获取obj1.这样就可以构成死锁.因为,当t1获取到obj1的时候,t1获取到了obj1锁,t2获取到了obj2锁,他们获取完毕之后.然后他们想要获取对方的锁,此时就构成了死锁.也就出现了BLOCKED状态.

public class ThreadDemo4 {
    public static void main(String[] args) throws InterruptedException {
        Object obj1 = new Object();
        Object obj2 = new Object();
        Thread t1 = new Thread(()->{
            synchronized (obj1){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (obj2){
 
                }
            }
        });
        Thread t2 = new Thread(()->{
            synchronized (obj2){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (obj1){
 
                }
            }
        });
 
        t1.start();
        Thread.sleep(100);
        t2.start();
        Thread.sleep(1500);
        System.out.println(t2.getState());
        t1.join();
        t2.join();
 
    }
}


版权声明:本文为m0_53882348原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。