线程的生命周期

废话不多写。首先我们先回顾回顾,理解下线程的生命周期,以及不同的阶段的区别:

新建状态(NEW)

当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配内存,
并初始化其成员变量的值

就绪状态(RUNNABLE)

当线程对象调用了 start()方法之后,该线程处于就绪状态。Java虚拟机会为其创建方法调用栈和
程序计数器,等待调度运行。

运行状态(RUNNING)

如果处于就绪状态的线程获得了 CPU,开始执行run()方法的线程执行体,则该线程处于运行状态。

阻塞状态(BLOCKED)

阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行。
直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice转到运行(running)状态。
阻塞的情况分三种:等待阻塞(o.wait->等待对列):运行(running)的线程执行o.wait方法,JVM会把该线程放入等待队列(waitting queue)中。同步阻塞(lock-〉锁池)运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。其他阻塞(sleep/join)运行(running)的线程执行Thread.sleep(long ms)或join方法,或者发出了 I/O请求时, JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O 处理完毕时,线程重新转入可运行(runnabl e)状态。

线程死亡(DEAD)

线程会以下面三种方式结束,结束后就是死亡状态:正常结束:run或call方法执行完成,线程正常结束。异常结束:线程抛出一个未捕获的Exception或Error。调用stop:直接调用该线程的stop方法来结束该线程,该方法通常容易导致死锁,不推荐使用。

线程的基本方法

线程等待(wait)

Object类中的wait()方法,调用该方法的线程进入WAITING状态,只有等待另外线程的通知或被中断才会返回,需要注意的 是调用wait方法后,会释放对象的锁。因此,wait方法一般用在同步方法或同步代码块中。简单的说就是:wait是对象通知持有自己锁的线程释放我的锁。

synchronized (obj) {while (<condition does not hold>)obj.wait();... // Perform action appropriate to condition}
该方法必须同步执行的,否则会抛出IllegalMonitorStateException

调用wait方法,首先会获取监视器锁monitor,获得成功以后,会让当前线程进入等待状态进入等待队列并且释放锁;然后当其他线程调用notify或者notifyall以后,会选择从等待队列中唤醒任意一个线程,而执行完notify方法以后,并不会立马唤醒线程,原因是有线程仍然持有这把锁,处于等待状态的线程无法获得锁。必须要等到线程执行完按monitorexit指令以后,也就是锁被释放以后,处于等待队列中的线程就可以开始竞争锁了。所以这里我们也能够理解为什么wait和notify等方法需要和synchronized一起使用了吧。

线程唤醒(notify、notifyAll)

唤醒在此对象监视器上等待的单个线程,如果所有线程都在此对象上等待,则会随机选择唤醒其中一个线程。线程通过调用其中一个wait()方法,在对象的监视器上等待,直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程,被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争。类似的方法还有notifyAll,唤醒再次监视器上等待的所有线程。简单的说就是:notify()/notifyAll()就是对象通知刚刚被自己晾在一边的线程又可以来竞争我的锁了。

  synchronized (obj) {while (<condition does not hold>)obj.wait();obj.notify();... // Perform action appropriate to condition} 

线程睡眠(sleep)

sleep导致当前线程休眠,与wait方法不同的是sleep不会释放当前占有的锁,sleep(long)会导致 线程进入TIMED-WATING状态,而wait。方法会导致当前线程进入WATING状态

线程让步(yield)

yield会使当前线程让出CPU执行时间片,与其他线程一起重新竞争CPU时间片。一般情况下, 优先级高的线程有更大的可能性成功竞争得到CPU时间片,但这又不是绝对的,有的操作系统对线程优先级并不敏感。

线程中断(interrupt)

中断一个线程,其本意是给这个线程一个通知信号,会影响这个线程内部的一个中断标识位。这 个线程本身并不会因此而改变状态(如阻塞,终止等)。

1. 调用interrupt)方法并不会中断一个正在运行的线程。也就是说处于Running状态的线 程并不会因为被中断而被终止,仅仅改变了内部维护的中断标识位而已。

2. 若调用sleep()而使线程处于TIMED-WATING状态,这时调用interrupt。方法,会抛出 InterruptedException,从而使线程提前结束 TIMED-WATING 状态。

3. 许多声明抛出 InterruptedException 的方法(如 Thread.sleep(long mills方法)),抛出异 常前,都会清除中断标识位,所以抛出异常后,调用isInterrupted()方法将会返回false。

4. 中断状态是线程固有的一个标识位,可以通过此标识位安全的终止线程。比如,你想终止 —个线程thread的时候,可以调用thread.interrupt()方法,在线程的run方法内部可以 根据thread.isInterrupted ()的值来优雅的终止线程。

所以怎么理解呢:

首先,一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。
所以,Thread.stop, Thread.suspend, Thread.resume 都已经被废弃了。
而 Thread.interrupt 的作用其实也不是中断线程,而是「通知线程应该中断了」,
具体到底中断还是继续运行,应该由被通知的线程自己处理。

Join等待其他线程终止

join方法,等待其他线程终止,在当前线程中调用自己的join()方法,则当前线程转为阻塞 状态,当其他线程结束,当前线程再由阻塞状态变为就绪状态,等待cpu的宠幸。

sleep 与 wait 区别

1、这两个方法来自不同的类,sleep是Thread,wait是属于Object

2、最主要是sleep方法没有释放锁,而wait方法释放了锁。sleep方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。wait方法直接释放了锁,调用唤醒方法后,需要重新竞争锁。

3、wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用

4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

5、sleep是Thread类的静态方法。sleep的作用是让线程答休眠制定的时间,在时间到达时恢复,也就是说sleep将在接到时间到达事件事恢复线程执行。wait是Object的方法,也就是说可以对任意一个对象调用wait方法,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。

start 与 run 区别

run只是Thread里面的一个普通方法,start是启动线程的方法。

start方法:

start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行其他的代码。真正的启动了一个线程。通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。然后通过此Thread类调用方法run()来完成其运行操作的,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程终止,而CPU再运行其它线程

run方法:

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

欢迎关注订阅号

为什么重新new两个线程线程号相同_面试官每次问我关于线程间通信方法,我都回答的很糟糕...相关推荐

  1. java线程池原理简答_面试官让我讲讲Java线程池的实现原理,我笑了...

    期待与你,一起进步 随着cpu核数越来越多,不可避免的利用多线程技术以充分利用其计算能力.所以,多线程技术是服务端开发人员必须掌握的技术. 线程的创建和销毁,都涉及到系统调用,比较消耗系统资源,所以就 ...

  2. 怎样实现两个线程共享一个集合_面试高频考察点:几种线程安全的Map解析

    Java中平时用的最多的Map集合就是HashMap了,它是线程不安全的. 看下面两个场景: 1.当用在方法内的局部变量时,局部变量属于当前线程级别的变量,其他线程访问不了,所以这时也不存在线程安全不 ...

  3. hashmap为什么线程不安全_面试官:你说 HashMap 线程不安全,它为啥不安全呢?...

    扫描下方海报 试读 本文来源: http://cnblogs.com/developer_chan/p/10450908.html 我们都知道HashMap是线程不安全的,在多线程环境中不建议使用,但 ...

  4. 如何把class里的vector结构体memcpy出来_面试官:请说出线程安全的 ArrayList 有哪些,除了Vector...

    以下环境是 JDK 1.8 ArrayList 的初始容量 面试官:你看过 ArrayList 的源码? Python 小星:看过 面试官:那你说下ArrayList 的初始容量是多少? Python ...

  5. arraylist 后往前遍历_面试官:请说出线程安全的 ArrayList 有哪些,除了Vector

    以下环境是 JDK 1.8 ArrayList 的初始容量 面试官:你看过 ArrayList 的源码? Python 小星:看过 面试官:那你说下ArrayList 的初始容量是多少? Python ...

  6. 前端的请求最大线程数是多少啊_面试官:创建多少个线程合适,我该怎么说?...

    转载:https://mp.weixin.qq.com/s/j5d4Jtxo0RgJWgpnG9HxlQ 为什么要使用多线程? 防止并发编程出错最好的办法就是不写并发程序 既然多线程编程容易出错,为什 ...

  7. 在c#中用mutex类实现线程的互斥_面试官经常问的synchronized实现原理和锁升级过程,你真的了解吗...

    本篇文章主要从字节码和JVM底层来分析synchronized实现原理和锁升级过程,其中涉及到了简单认识字节码.对象内部结构以及ObjectMonitor等知识点. 阅读本文之前,如果大家对synch ...

  8. mysql 钩子_面试官: 什么是 Hook (钩子) 线程以及应用场景?

    一.Hook 线程介绍 通常情况下,我们可以向应用程序注入一个或多个 Hook (钩子) 线程,这样,在程序即将退出的时候,也就是 JVM 程序即将退出的时候,Hook 线程就会被启动执行. 先看一段 ...

  9. 面试官让我讲下线程的WAITING状态,我笑了

    转载自  面试官让我讲下线程的WAITING状态,我笑了 面试官Q:你讲下线程状态中的WAITING状态,什么时候会处于这个状态?什么时候离开这个状态? 小菜J 会心一笑... 一个正在无限期等待另一 ...

最新文章

  1. C# SVN检出的代码,F12显示从元数据
  2. 第四讲:debugging simulation mismatches
  3. Haproxy+Percona-XtraDB-Cluster 集群
  4. MUI 图标显示不出来 - 分析篇
  5. python类定义中__init__()_转:python学习——类中为什么要定义__init__()方法
  6. php 上传文件 例子,php上传文件实例
  7. 工信部回应“网传4G降速”:从未要求运营商降速
  8. document-scanner:一个基于OpenCV的文档扫描器
  9. prepareStatament和Statement和callableStatement的区别
  10. 细说ConcurrentHashMap扩容规则
  11. 高德地图API(使用浏览器ip实现精确定位)
  12. javaFX,Scene Builder引入Jfoenix
  13. Mac中彻底删除搜狗拼音输入法一法
  14. 软件测试——课程感想
  15. 恢复被文件夹病毒恶意隐藏的文件夹
  16. PADS-VX入门到精通实战项目讲解(上)—LOGIC部分-覃小刚-专题视频课程
  17. C++ primer plus 第六章课后习题
  18. ARCore之路-连接设备调试应用
  19. CAD如何修改标注样式?
  20. 试着编写了一下战网的登录页面,刚学会css和html5

热门文章

  1. 学C++,能不能简单点?
  2. 腾讯35亿美元抄底收购搜狗,产品张小龙和技术王小川双剑合璧
  3. 学了这些,他薪资涨了40%,收割了阿里、头条、快手等大厂的offer!
  4. 用Python来分析5天破10亿的哪吒,为啥这么火?
  5. 全网最简单的dubbo源码调试,建议点赞收藏!!!
  6. Python3.5源码分析-内存管理
  7. MATLAB_no.1:入门作业_histeq():_imhist()_(男孩的三个图,以及文字描述)
  8. ACMNO.46 A+B问题 问题描述 输入A、B,输出A+B。(别被数值范围所局限)
  9. 代替以前的F5,Ctrl+r!
  10. 最大公约数与最小公约数!_只愿与一人十指紧扣_新浪博客