Java线程的几种状态

目录

一,了解状态.

二.线程之间的转换

 三,线程的状态演示

3.1 NEW和TERMINATED

3.2 RUNNABLE和TIME_WAITING

3.3 WAITING

3.4 BLOCKED


一,了解状态.

状态是针对当前的线程调度的情况来描述的.我们现在认为线程是调度的基本单位.因此状态更应该是线程的属性(谈到状态一般都是考虑线程的状态).

而在Java中,对于线程的状态进行了细化.有以下几种:

1.NEW : 表明创建了Thread对象但是还没有调用start方法(内核中还没有创建对应的PCB,也没有创建相应的线程).

2. TERMINATED : 表示内核中的PCB已经释放了,但是Thread对象还在.

3.RUNNABLE : 可运行的.包括 a)正坐在CPU上执行的.b) 在就绪队列里,可以随时去CPU上运行的.

4.表示阻塞的状态:

WAITING,TIMED_WAITING,BLOCKED.这三种都是表示阻塞,但是形成的原因不同.

二.线程之间的转换

线程的转换就由下面这张图来解释(图比较丑,手残).

 三,线程的状态演示

3.1 NEW和TERMINATED

public class ThreadDemo1 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
           for(int i = 0;i<1000000;i++){

           }
        });
        //t调用start之前,是NEW状态.
        System.out.println("线程执行之前:"+t.getState());
        t.start();
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //线程执行完毕之后,就是TERMINATED状态.
        System.out.println("线程执行之后:"+t.getState());
    }
}

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

3.2 RUNNABLE和TIME_WAITING

public class ThreadDemo1 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
           for(int i = 0;i<1000;i++){

           }
        });
        System.out.println("线程执行之前:"+t.getState());
        t.start();
        //线程处于可执行状态
        System.out.println("线程运行中:"+t.getState());
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("线程运行完:"+t.getState());
    }
}

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

如果在Thread里进行sleep操作,在main里使用循环进行获取状态操作.代码如下:

public class ThreadDemo1 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
           for(int i = 0;i<1000;i++){
               try {
                   Thread.sleep(10);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        });
        System.out.println("线程执行之前:"+t.getState());
        t.start();
        for(int i = 0;i<1000;i++){
            System.out.println("线程运行中:"+t.getState());

        }
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("线程运行完:"+t.getState());
    }
}

 

就可能会出现这样的交替状态.当前获取到的状态,完全取决于系统的调度操作.(t线程是正在执行还是在sleep) 

3.3 WAITING

public class ThreadDemo2 {
    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());
    }
}

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

3.4 BLOCKED

public class ThreadDemo3 {
    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();

    }
}

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值