高并发(4)- 线程的状态

2020-03-27  本文已影响0人  残冬十九

前言

上篇文章讲解了多线程的停止方法。我们本篇文章来讲讲多线程的运行状态。


一、多线程的运行状态。

我们都知道,线程分为新建、就绪、运行、阻塞、死亡这几种状态,这些状态分别是什么意思呢,来看一下。

新建:指的是线程新创建出来,并没有运行start方法,这时候就是新建状态,没有运行代码。

就绪:就绪状态指的是线程调用了start方法,线程准备就绪,争抢cpu,当抢到cpu的时候,才可以进行执行代码。因为在单CPU的计算机系统中,不可能同时运行多个线程,一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。

运行:运行值得是线程抢到了cpu的后,进入运行状态,执行run方法, 开始实际的代码运行。

等待:等待是join或者wait之后线程需要等待所依赖或被唤醒的等待状态。

阻塞:阻塞状态是线程运行中,由于某些原因进入阻塞状态。例如线程通过sleep方法进入睡眠状态,等待触发某个条件。阻塞状态就是正在运行的线程没有结束,暂时让出cpu,这时候其他处于运行状态的线程就可以获取cpu,进入运行状态。

死亡:死亡状态是指线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

二、线程状态的变化

线程的状态变化如下:

image image.gif

其中涉及到了yield方法和join方法,来讲解一下。

yield方法是:暂停当前执行的线程,放弃cpu资源,执行其他线程。是让线程从运行状态回到可运行状态,但是实际无法保证yield()可以达到让步的目的,因为当前线程可以能会再次抢占到CPU。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果

join方法是:Join把指定的线程加入到当前线程,可以把交替执行的两个线程合并为顺序执行,例如线程B调用线程A的join方法,那么将先执行完A线程,才会执行线程B,如下面代码所示

/**
 * @version 1.0
 * @Description joinDemo
 * @Author wb.yang
 */
public class JoinDemo {

    /**
     * 女神
     */
    static class Goddess implements Runnable {
        private Thread thread;

        public Goddess(Thread thread) {
            this.thread = thread;
        }

        @Override
        public void run() {
            System.out.println("Goddess开始排队打饭.....");
            try {
                if (thread != null) {
                    thread.join();
                }
            } catch (InterruptedException e) {
            }
            //休眠2秒
            SleepTools.second(2);
            System.out.println(Thread.currentThread().getName()
                    + " Goddess打饭完成.");
        }
    }

    /**
     * 女神的男朋友
     */
    static class GoddessBoyfriend implements Runnable {

        @Override
        public void run() {
            //休眠2秒
            SleepTools.second(2);
            System.out.println("GoddessBoyfriend开始排队打饭.....");
            System.out.println(Thread.currentThread().getName()
                    + " GoddessBoyfriend打饭完成.");
        }
    }

    public static void main(String[] args) throws Exception {

        // 女神的男朋友
        GoddessBoyfriend goddessBoyfriend = new GoddessBoyfriend();
        Thread gbf = new Thread(goddessBoyfriend);
        // 女神,把女神的男朋友线程放入女神中
        Goddess goddess = new Goddess(gbf);
        // 汤姆
        Thread tom = new Thread(goddess);
        tom.start();
        gbf.start();
        System.out.println("汤姆开始排队打饭.....");
        tom.join();
        //让主线程休眠2秒
        SleepTools.second(2);
        System.out.println(Thread.currentThread().getName() + " 汤姆打饭完成.");
    }
}
image.gif
    从代码中可以看出总共有三个线程,汤姆,女神,女神男朋友三个线程,如果正常的线程的话,执行顺序是不一定的,就是说这个是那个线程都有可能先执行完,然后看看执行结果把。
image image.gif

   从结果中看出,线程是有执行顺序的,这就是因为我们用了join方法,在汤姆的线程中调用了女神线程的join方法,所以汤姆线程就要等待女神线程先执行完毕,而在女神线程中,有调用的女神男朋友的线程,所以又要等待女神男朋友线程的执行完毕,所以最终结果就是女神男朋友先打完饭,然后是女神,最后是汤姆。这就是join方法的作用。

总结

1.线程的五种状态,新建、就绪、运行、阻塞、死亡

2.线程的两个方法,yield和join方法

上一篇 下一篇

猜你喜欢

热点阅读