线程的 run()和 start()有什么区别?
线程状态之间的转换:https://www.cnblogs.com/zhaosq/p/10564698.html
1.start():
用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体中的代码执行完毕而直接继续执行后续的代码。通过调用Thread类的 start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里的run()方法称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
2.run():
run()方法只是类的一个普通方法而已。run方法相当于线程的任务处理逻辑的入口方法,就是线程体,它由java虚拟机在运行相应线程时直接调用,而不是由代码进行调用。
3.总结:排队玩游戏机
多线程原理相当于玩游戏机,只有一个游戏机(CPU),start是排队,等CPU轮到你,你就run。
调用start后,线程会被放入到等待队列中,也就是上面说的就绪状态,等待CPU调用,并不是马上调用。然后通过JVM,线程thread会调用run方法,执行本线程的线程体,先调用start,后调用run。为什么不直接调用run呢?为了实现多线程的优点。
4.线程状态说明
线程状态从大的方面来说,可归结为:初始状态、可运行状态、不可运行状态和消亡状态,具体可细分为上图所示7个状态,说明如下:
1)线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,当我们new了Thread实例后,线程就进入了初始状态;
2)当该对象调用了start()方法,就进入可运行状态;
3)进入可运行状态后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态;
4)进入运行状态后涉及的情况就比较多,大致有如下情形: ﹒
run()方法或main()方法结束后,线程就进入终止状态;
当线程调用了自身的sleep()方法或其他线程的join()方法,就会进入阻塞状态(该状态虽停止当前线程,但并不释放所占有的资源)。
当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配时间片;
当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被锁住(synchroniza,lock),将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入可运行状态,等待OS分配 CPU时间片;
当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由于不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。
当线程调用stop方法,即可使线程进入消亡状态,但是由于stop方法是不安全的,不鼓励使用,大家可以通过run方法里的条件变通实现线程的 stop。
5.sleep()和wait()的区别
sleep()方法正在执行的线程主动让出CPU(然后CPU就可以去执行其他任务),在sleep指定时间后CPU再回到该线程继续往下执行(注意:sleep方法只让出了CPU,而并不会释放同步资源锁!!!);wait()方法则是指当前线程让自己暂时退让出同步资源锁,以便其他正在等待该资源的线程得到该资源进而运行,只有调用了notify()方法,之前调用wait()的线程才会解除wait状态,可以去参与竞争同步资源锁,进而得到执行。(注意:notify的作用相当于叫醒睡着的人,而并不会给他分配任务,就是说notify只是让之前调用wait的线程有权利重新参与线程的调度);sleep()方法可以在任何地方使用;wait()方法则只能在同步方法或同步块中使用;sleep()是线程线程类(Thread)的方法,调用会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复;wait()是Object的方法,调用会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,不再次获得对象锁才会进入运行状态;
6.notify()和notifyAll()的区别
如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁;
线程的 run()和 start()有什么区别?相关推荐
- 线程的 run() 和 start() 有什么区别?
线程的 run() 和 start() 有什么区别? 调用 start() 方法是用来启动线程的,轮到该线程执行时,会自动调用 run():直接调用 run() 方法,无法达到启动多线程的目的,相当于 ...
- 多线程面试题之启动一个线程是run()还是start()?他们有什么区别
3.启动一个线程是run()还是start()?他们有什么区别启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行.这并不意味着线程就会立即运 ...
- 多线程中 start()和run()方法的区别
多线程中 start()和run()方法的区别: Java线程一直是一个比较容易困扰的地方,首先,我们来认识下怎样生存线程. 认识 Thread 和Runnable java中实现多线程有两种途径: ...
- C# Task.Run 和 Task.Factory.StartNew 区别
有小伙伴问我,为什么不推荐他使用 Task.Factory.StartNew ,因为 Task.Run 是比较新的方法. 本文告诉大家 Task.Run 和 Task.Factory.StartNew ...
- docker run与docker start的区别?
docker run相当于执行了两步操作:将镜像放入容器中(docker create),然后将容器启动,使之变成运行时容器(docker start). docker start的作用是:重新启动已 ...
- java 多线程 start,Java 线程的run()和start()
Java 线程的run()和start() 一个常见的问题:为什么启动线程是调用start()方法,而不是调用run()方法呢? 答案: 每个线程都在单独的调用堆栈中启动. 从主线程调用run()方法 ...
- 线程中断的三个方法的区别(interrupt/isInterrupted/interrupted)
线程中断的三个方法的区别(interrupt/isInterrupted/interrupted)-总结自Java编程之美 方法定义 void interrupt():中断调用该方法的实例线程对象.当 ...
- yarn build 和 npm run build打包有什么区别
yarn build 和 npm run build打包有什么区别 结论: 没区别,yarn build === yarn run build === npm run build
- 线程与进程之间的关系和区别
线程共享的环境包括:进程代码段,进程的公有数据(利用这些数据,线程很容易实现相互间的通讯),进程打开的文件描述符,信号的处理器进程的当前目录和进程用户ID与进程组ID. 进程拥有这许多共性的同时,还拥 ...
最新文章
- mysql5.7.22密码设置_mysql5.7.22版本修改root密码
- 我们为什么不能只相信建立在深度学习基础上的人工智能系统
- Gartner:2018年十大科技趋势与其对IT和执行的影响
- _不懂操作?手把手教你如何在linux下搭建FTP
- apache FilesMatch
- 诊断虚拟机频繁 OOM 的问题
- java简易扑克牌_简易扑克牌游戏(java)
- 浏览器同源策略及其规避方法
- 【Leetcode】数学题(Python)
- Java读取共享文件夹下面的文件(利用smb协议)
- 中职学校计算机技能大赛总结,中职学校技能大赛总结
- select标签 selected 选中状态动态查询
- 2016.03.07错误记录
- Fleck说明文档翻译
- NR 5G 系统信息
- linux系统命令cd怎么使用,linux命令怎么用_Linux cd命令该怎么使用
- 安卓统一推送联盟,终于有消息了,统一推送时间表出炉
- PL/SQL Developer 登录报错(ORA-12547)解决方案
- 站长导航系统源码-修复版
- 云和恩墨大讲堂 X openGauss Meetup X 鲲鹏生态孵化营(上海站)完美落幕!