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()方法可以给一个参数,参数代表执行的毫秒; 

    第五个状态 死亡状态

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

  • 相关阅读:
    bzoj1101 [POI2007]Zap
    bzoj2648/2716 kdtree
    bzoj2850巧克力王国
    【bzoj1193】[HNOI2006]马步距离
    bzoj 4401 块的计数 思想+模拟+贪心
    【bzoj2751】[HAOI2012]容易题(easy) 数论,简单题
    Ubuntu分区小知识与分区方案
    Ubuntu16.04安装x11VNC远程桌面
    Ubuntu用户权限管理(chown, chmod)
    Ubuntu新建用户组
  • 原文地址:https://www.cnblogs.com/StanleyBlogs/p/10894463.html
Copyright © 2011-2022 走看看