目录

  • start()与run()方法区别
  • 多线程抢占式运行原理

start()与run()方法区别

我们通过一个例子来进行总结,我们写一个利用Thread创建的简单的多线程例子,然后分别执行start()与run()方法,执行结果如下所示:

/*** @author :zjc* @ProjectName: execises* @Package: com.execises.zjc.controller.thread* @ClassName: ThreadRunAndStartMethodCompare* @date :Created in 2021/7/17 10:20* @description:对比run()和start()方法* @modified By:* @version: v1.0.0$*/
public class ThreadRunAndStartMethodCompare extends Thread {private String name;public ThreadRunAndStartMethodCompare(String name) {this.name = name;}@Overridepublic void run() {super.run();System.out.println(name);}public static void main(String[] args) {new ThreadRunAndStartMethodCompare("唐山大兄本兄").run();//new ThreadRunAndStartMethodCompare("唐山大兄本兄").start();}}

这里先执行了start()方法

在执行时,我们看到新生成了一个线程,这样与主线程分离开,实现了并行执行。

start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码:

1、通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。
2、然后通过此Thread类调用方法run()来完成其运行操作,这里方法run()称为线程体,它包含了要执行的这个线程的内容。
3、run()方法运行结束,此线程终止,而CPU再运行其它线程。

执行run方法

run()方法在这里可以看到并没有线程产生,只有单独的主进程

只是当作普通方法的方式调用,程序还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码。在这里我们是直接用run()方法,这只是调用一个方法而已,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,这样就没有达到写线程的目的。

Thread底层也是用Runnable的run()方法来执行,其中target就是Runnable的变量名。

    @Overridepublic void run() {if (target != null) {target.run();}}

Thread对象的run()方法在一种循环下,使线程一直运行,直到不满足条件为止,在你的main()里创建并运行了一些线程,调用Thread类的start()方法将为线程执行特殊的初始化的过程,来配置线程,然后由线程执行机制调用run()方法。如果你不调用start()方法,线程就不会启动。

因为线程调度机制的行为是不确定的,所以每次运行该程序都会有不同的结果,你可以把你的循环次数增多些,然后看看执行的结果,你会发现main()的主线程和Thread子线程是交替运行的。我们看下面一段代码:

/*** @author :zjc* @ProjectName: execises* @Package: com.execises.zjc.controller.thread* @ClassName: ThreadOpByThread* @date :Created in 2021/7/16 15:03* @description:创建多线程之继承Thread类* @modified By:* @version: v1.0.0$*/
public class ThreadOpByThread extends Thread {@Overridepublic void run() {super.run();for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName() + i);}}static class testThread {public static void main(String[] args) {ThreadOpByThread threadOpByThread = new ThreadOpByThread();threadOpByThread.start();for (int i = 0; i < 100; i++) {System.out.println("我是主线程"+ i);}}}}

输出结果为:

我是主线程0
Thread-00
我是主线程1
Thread-01
Thread-02
Thread-03
Thread-04
Thread-05
我是主线程2
我是主线程3
我是主线程4
我是主线程5
我是主线程6
我是主线程7
我是主线程8
Thread-06

在执行过程中会相互并发穿插执行,子线程执行完毕后依然会回到主线程,交给主线程最终执行,这也就是并发执行的高效率之所在。

多线程抢占式运行原理

经过我运行下面这段代码,发现每次生成的线程顺序号都是会变的,并不是按照顺序来执行:

/*** @author :zjc* @ProjectName: execises* @Package: com.execises.zjc.controller.thread* @ClassName: ThreadRunAndStartMethodCompare* @date :Created in 2021/7/17 10:20* @description:对比run()和start()方法* @modified By:* @version: v1.0.0$*/
public class ThreadRunAndStartMethodCompare extends Thread {private String name;public ThreadRunAndStartMethodCompare(String name) {this.name = name;}public ThreadRunAndStartMethodCompare() {}@Overridepublic void run() {super.run();System.out.println(name);}public static void main(String[] args) {ThreadRunAndStartMethodCompare threadRunAndStartMethodCompare = new ThreadRunAndStartMethodCompare();//new ThreadRunAndStartMethodCompare("张建超").run();for (int i = 0; i < 100; i++) {threadRunAndStartMethodCompare.demo(i);}}public void demo(int i) {synchronized (this) {new ThreadRunAndStartMethodCompare("唐山大兄本兄" + i).start();}}}

输出结果:

唐山大兄本兄0
唐山大兄本兄5
唐山大兄本兄3
唐山大兄本兄2
唐山大兄本兄1
唐山大兄本兄4
唐山大兄本兄6
唐山大兄本兄7
唐山大兄本兄8
唐山大兄本兄10
唐山大兄本兄18
唐山大兄本兄12
唐山大兄本兄20
唐山大兄本兄13
唐山大兄本兄14


原因:

1、当java虚拟机(也就是经常说的 JVM)执行mian方法的时候,他会找操作系统(也就是os)开辟一条main方法通向cpu的路径,这个路径就是main线程,也就是所说的主线程。

2、接着cpu通过这个线程,也就是这个路径,就可以执行main方法了。

3、当我们new了一个Thread对象,这个时候又开辟了一条通向cpu的路径,而这条路径是用来执行run方法的。

4、而现在对于cpu而言,他就有了很多条执行的路径,cpu就有了选择的权利,cpu他喜欢谁,就会执行哪条路径,我们是控制不了cpu的,所有就有了出现随机打印的结果。

反过来说,两个线程,一个main线程,一个新线程,他们一起抢夺cpu的执行权(即 cpu的执行时间),谁抢到了,谁先执行。

也可以这么来理解:

0到99这段时间太短,对于CPU分配给这个线程的时间片来说足够完成了,也就呈现出0到99个线程同时初始化,然后剩下的线程再争夺CPU资源,在我们Debug调试的时候输出就是0到99的顺序,不用Debug调试直接运行就不是0到99输出。大致可以理解为创建了所有的线程,再争用资源。调试的时候有断点,产生了优先级,所以才按序输出的。

这边发现一个讲run()和start()的比较详细的文章,链接地址放在这里:
https://blog.csdn.net/chengp919/article/details/77336328

欢迎感兴趣的小伙伴一起探讨学习知识,以上是个人的一些总结分享,如有错误的地方望各位留言指出,十分感谢。

觉得有用的话别忘点赞、收藏、关注,手留余香!

start()方法和run()方法区别与多线程抢占式运行原理相关推荐

  1. 并发基础篇(六):线程Thread类的start()方法和run()方法

    点个赞,看一看,好习惯!本文 GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了 3 个月总结的一线大厂 Java 面试总结,本 ...

  2. 线程Thread类的start()方法和run()方法

    一.初识 java的线程是通过java.lang.Thread类来实现的.VM启动时会有一个由主方法所定义的线程.可以通过创建Thread的实例来创建新的线程.每个线程都是通过某个特定Thread对象 ...

  3. PIL库中Image类thumbnail方法和resize方法区别

    from PIL import Image   im=Image.open("C:\\Users\\kethur\\Desktop\\a.jpg") x,y=im.size pri ...

  4. Thread start()方法和run()方法的区别

    Thread start() 方法 ,是一个线程开始的方法 Thread run() 方法 ,就是一个普通的方法,可以理解为main方法里面的一个普通的方法 下面写一个demo 理解下 Thread ...

  5. Python生成器next方法和send方法区别详解

    yield的语法规则是: 在yield这里暂停函数执行,并返回yield后面表达式的值(默认为None),直到被next()再次调用时,从上次暂停的yield代码处继续往下执行.当没有可继续next( ...

  6. compareto方法_compare方法和compareTo方法区别

    字符串数组sort方法是默认按照字典顺序排序 对象数组 按照对象的某字段排序可以用compare和compareTo两种方法 对对象数组排序: 1.compare 方法得用一个单独继承java.uti ...

  7. PreparedStatement 的 execute方法和executeUpdate方法区别

    方法executeUpdate 用于执行 INSERT.UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE.INSE ...

  8. awakeFromNib方法和viewDidLoad方法区别

    当.nib文件被加载的时候,会发送一个awakeFromNib的消息到.nib文件中的每个对象,每个对象都可以定义自己的awakeFromNib函数来响应这个消息,执行一些必要的操作. 也就是说只有通 ...

  9. ThinkPHP 中M方法和D方法的具体区别

    M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...

最新文章

  1. 一文看透 Redis 分布式锁进化史(解读 + 缺陷分析)(转)
  2. 47.nginx+tomcat群集
  3. 实战项目---模拟商品采购中心信息平台
  4. python使用os.listdir和os.walk获得文件的路径
  5. 7-46 银行排队问题之单队列多窗口服务 (10 分)
  6. java int ==_Java 位运算符和 int 类型的实现
  7. java sql update用法_使用if else条件将SQL UPDATE语句转换为php(codeigniter)
  8. lily+Solr 原理与配置
  9. Hadoop配置文件详解
  10. 天天都在数据驱动,你以为数据是天上掉下来的?
  11. linux sar 分析,Linux性能测试分析命令_sar
  12. 成都涌现大量网游业创业团队:从业人员近3万(网游亦可创业)
  13. 原神pc端服务器切换工具,基于python3
  14. 网络训练 (总结5)
  15. 高校邦python程序设计基础_高校邦Python程序设计基础【实境编程】答案
  16. 【菜菜的sklearn课堂笔记】决策树-分类树
  17. activemq、rabbitmq、kafka原理和比较
  18. 出现了,PPT 制作新方式
  19. 移动互联的“大熊猫”——优秀前端工程师
  20. 【JavaScript框架封装】自己动手封装一个涵盖JQuery基本功能的框架及核心源码分享(单文件版本)

热门文章

  1. 推荐几个免费发布文章的网站
  2. 【PTA题目解答】7-7 调查电视节目受欢迎程度
  3. 阶乘逆元与组合数模板
  4. 电系魔法师成长之路—仪器仪表学习(二)设计T型和Π型衰减器
  5. 【Tableau server 】Tableau 如何用javaScript嵌入web前端网页?
  6. 手机短信中特殊字符导致链接失效的问题修复
  7. SRE之SLI/SLO设定
  8. 1471. 风水 解题报告
  9. Echarts分段仪表盘
  10. ArcGIS初学者的建议一(自带资源利用)