zoukankan      html  css  js  c++  java
  • 深入理解并发编程 -- 多线程(二)底层运行原理、线程状态

    并发编程 -- 多线程底层运行原理、线程状态

    作者 : Stanley 罗昊

    多线程 -- 并发编程(一) : https://www.cnblogs.com/StanleyBlogs/p/10890906.html

    转载请注明出处和署名,谢谢!

    多线程底层执行原理

    说道底层运行,那么是不是就是需要依靠CPU啊;

    那,各位之前有没有听过一句话叫做,一个CPU在同一个时间片只能执行一个程序

    什么意思呢?

    就是,你的程序是不是都运行在一个CPU上啊,那你真正一个CPU在同一个时间片里是不是只能执行一个程序呀,那这个程序究竟要执行那个程序,是不是就需要通过线程之间时间片的一个争抢;

    时间片:微小的时间段;

    多线程说白了就是时间片的争夺,那个线程获取了时间片,就执行那个线程的代码;

    假设,t1线程先获得时间片,那么,t1线程就优先执行;

    但是,它不可能拿着那个时间片不放吧,因为在CPU执行的过程中,底层运用轮循制的;

    多线程执行的时候,CPU分配时间片是采取轮循的方式进行分配的;

    就是轮流,有点像值日的时候,轮流值日一样;

    那,CPU在分配时间片的时候,第一个t1先抢占到了之后,他先执行了一段时间之后,CPU把这个t1执行完了以后,CPU是不是接着把时间片分配给t2去执行了;

    那事实上,也是t2也在去抢占时间片

    t1执行完毕后,那么,CPU就将迎来新的一轮争夺,这个时候t2抢到了,就开始执行t2的代码;

    这就是多线程的底层执行原理;

    多线程它在本质上运行的时候,他是同时执行的,还是轮流执行的呢?

    肯定不是同时执行的,也就是不是我们常说的并发执行;那在你们看来,实际就是宏观上你来看就是同时执行,但是在微观上是不是的;

    线程的状态

    线程总共有五种状态;

    第一个状态 新建状态

    新建状态,就是你新建一个线程是的状态,也就是你新建了一个线程但还没有启动时的状态;

    当线程执行start方法的时候,就会进入就绪状态;

    第二个状态 就绪状态

    进入就绪状态的时候,事实上就是准备抢占CPU的时间片;

    一旦抢占到了CPU的时间片它就会立即进入运行状态;

    第三个状态 运行状态

    当线程抢占到了CPU时间片的时候,它才会运行,所以第三个状态是,运行状态;

    在它的运行状态中,还有可能执行一个代码,Throad.sleep();睡眠;

    就是在你执行的时候,突然让你睡眠了,我都让你这个线程睡眠了,你还有必要去争夺这个CPU资源吗?

    就肯定没有必要再去争夺这个CPU资源了,那这个时候你就需要释放CPU啊,对不对,你释放之后,你下次再运行的时候,你就需要重新获取CPU的时间片,所以这种状态就叫做堵塞状态;

    第四个状态 堵塞状态与sleep方法

    想让线程阻塞,最常用的方式就是使用sleep,用sleep这个方法,可以使运行中的线程回到就绪状态;

    因为它需要重新抢占CPU资源的,所以,sleep状态的最终目的是让改线程回到就读状态;

    就比如,我现在想让这个线程,进我想让它每次进入run方法中的for循环打印里写一个睡眠,一遍循环遍历输出,一边睡眠看会发生什么:

    我在run方法中业务写完后,我们测试一下该线程:

    在上图中,可以发现,我同时调用了两次start方法,说明,我执行了两次我一次性开启了两次线程,并且执行了两次,我们看看会不会出现交替执行的情况:

    从输出结果来看,确实交替执行了并且,是俩俩执行的:

    每过一秒,就会执行一次:

    我就不继续演示了;

    所以,我们从中可以看出,不管哪个线程过来,t1也好t2也好,执行的时候,均睡眠一秒钟,睡眠完一秒钟之后,谁先醒了,谁就继续向下执行,这个就是到点自然醒的;

    也可以使用join来造成线程堵塞;

    join

    刚刚,我们在上面介绍了sleep,我们来看看join;

    join():是线程加入

    它底层执行的是,当你在执行一个线程的时候,如果遇到其他线程加入,则会先执行加入的线程,直到的加入的线程执行完成,才会继续执行原来线程的任务;

    什么意思呢?

    就是说,还是上面那个t1,与t2的例子,那假设说,t1在执行的过程中,突然遇到了一个代码t2.join,这时候,就会在这个时间片,优先执行t2的线程;

    join()方法可以给一个参数,参数代表执行的毫秒; 

    第五个状态 死亡状态

    线程执行完了,或因异常退出了,都会结束生命周期,这就是死亡状态;

  • 相关阅读:
    elasticsearch 中的Multi Match Query
    activiti 流程部署的各种方式
    elasticsearch 嵌套对象之嵌套类型
    elasticsearch Java High Level REST 相关操作封装
    elasticsearch 字段数据类型
    ubuntu 安装 docker
    elasticsearch 通过HTTP RESTful API 操作数据
    facenet 人脸识别(二)——创建人脸库搭建人脸识别系统
    POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)
    墨卡托投影, GPS 坐标转像素, GPS 坐标转距离
  • 原文地址:https://www.cnblogs.com/StanleyBlogs/p/10894463.html
Copyright © 2011-2022 走看看