【Java】多线程基础(二)


上篇介绍了线程的几种创建方式,以及各种方式的原理,这篇我们来学习一下线程的状态

2. 线程的状态

当线程创建并启动之后,并不是直接就进入运行状态。同样也不是运行之后也是一直处于运行状态。和生命一样也会有起始和终止。线程一般会经过 新建就绪运行阻塞死亡五个状态,下面逐一介绍

2.1 新建(New)

上一篇我们介绍线程的创建方式的时候就讲过,通过 new Thread 方式是创建了一个 Thread 对象。所以这时候的线程就处于新建状态。

2.2 就绪(Runnable)

通过调用start()方法,启动线程的时候,这时候线程处于就绪状态。

2.3 运行(Running)

当线程调用 start() 方法之后,native 执行到run() 方法时,此时的线程就处于运行状态。

这里可能会有人问,start()方法启动了线程,不应该就是运行了吗?我们要注意,start() 方法是一个 native 方法,并不会立刻执行run() 方法, run()方法的运行是底层操作系统控制。

2.4 阻塞(Blocked)

当线程数大于处理器数的时候,如果我们想要执行多个任务的话只有两种方式: **依次执行 **,交叉执行,这时候就涉及到了线程的阻塞了。操作系统中线程抢占运行的时候,如果某个线程没有抢占到,或者是自己调用了阻塞方法,这时候线程就处于阻塞状态。等到下次通知后才会继续运行。

线程从运行状态进入阻塞黄台可以分以下几种:

  • 线程调用 sleep
  • 线程执行了一个阻塞 io 的方法
  • 线程等待同步锁
  • 线程在等待某个通知(notify)
  • 线程调用了挂起方法(suspend)

反之线程则可以从阻塞状态进入就绪状态。

2.5 销毁(Dead)

线程运行结束,进入死亡状态。存在以下几种情况:

  • 当线程的 run (Callable 中的 call )方法执行完成
  • 线程调用 stop 方法
  • 线程运行中出现了异常

拓展

已经进入 Dead 状态的线程不可以再调用 start 方法,原因在于调用 start 方法时候 会检查线程的状态,如果不是新建(New)状态则会报异常

    //Thread.java 源码
    public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        ...
    }

2.6 线程状态间转换

线程状态切换

通过上面图示可以看出几点:

  • 阻塞状态只可以回到就绪状态

  • 运行态回到就绪状态可以通过运行状态 -> 阻塞状态 ->就绪状态 或者 yield 方法直接进入 就绪态

  • yield 方法是一个 native 方法,表示当前线程可以放弃对处理器的使用,这样操作系统处理的时候可以运行其他线程,源码介绍为

    A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.
    Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilise a CPU. Its use should be combined with detailed profiling and benchmarking to ensure that it actually has the desired effect.
    It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package.
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0neXiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值