Java线程的生命周期

一个线程的产生是从我们调用了start方法开始进入Runnable状态,即可以被调度运行状态,并没有真正开始运行,调度器可以将CPU分配给它,使线程进入Running状态,真正运行其中的程序代码。线程在运行过程中,有以下几个可能的去向:

(1)调度器在某个线程的执行过程中将CPU分配给了其它线程,则这个线程又变为Runnable状态,等待被调度。

(2)调度器将CPU分配给了该线程,执行过程中没有遇到任何阻隔,运行完成直接结束,也就是run()方法执行完毕。

(3)线程在执行过程中请求锁,却得不到,这时候它要进入lock pool中等待对象的锁,等到锁后又会进入Runnable状态,可以被调度运行。

(4)线程在执行过程中遇到wait()方法,它会被放入wait pool中等待,直到有notify()或interrupt()方法执行,它才会被唤醒或打断进入lock pool开始等待对象锁,等到锁后进入Runnable状态。

推荐在run方法中使用控制循环条件的方式来结束一个线程。

wait:告诉当前线程放弃对象锁并进入等待状态,直到其他线程进入同一对象锁并调用notify为止。

notify:唤醒同一对象锁中调用wait的第一个线程。

notifyAll:唤醒同一对象锁中调用wait的所有线程,具有最高优先级的线程首先被唤醒并执行。

yield:如果知道已经完成了在run()方法的循环的一次迭代过程中所需要的工作,就可以给线程调度一个机制暗示:我的工作已经做的差不多了,可以让给别的线程使用CPU了。通过调用yield()来实现。
当调用yield时,你也是在建议具有相同优先级的其他线程可以运行。
对于任何重要的控制或在调整应用时,都不恩那个依赖于yield。实际上,yield经常被误用。
(yield并不意味着退出和暂停,只是,告诉线程调度如果有人需要,可以先拿去,我过会再执行,没人需要,我继续执行)
调用yield的时候锁并没有被释放。

interrupt简述

interrupt() 方法只是改变中断状态而已,它不会中断一个正在运行的线程。这一方法实际完成的是,给受阻塞的线程发出一个中断信号,这样受阻线程就得以退出阻塞的状态。 更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,此时调用该线程的interrupt()方法,那么该线程将抛出一个 InterruptedException中断异常(该线程必须事先预备好处理此异常),从而提早地终结被阻塞状态。如果线程没有被阻塞,这时调用 interrupt()将不起作用,直到执行到wait(),sleep(),join()时,才马上会抛出 InterruptedException。

线 程A在执行sleep,wait,join时,线程B调用线程A的interrupt方法,的确这一个时候A会有 InterruptedException 异常抛出来。但这其实是在sleep,wait,join这些方法内部会不断检查中断状态的值,而自己抛出的InterruptedException。 如果线程A正在执行一些指定的操作时如值,for,while,if,调用方法等,不会去检查中断状态,则线程A不会抛出 InterruptedException,而会一直执行着自己的操作。

注意:

当线程A执行到wait(),sleep(),join()时,抛出InterruptedException后,中断状态已经被系统复位了,线程A调用Thread.interrupted()返回的是false。

如果线程被调用了interrupt(),此时该线程并不在wait(),sleep(),join()时,下次执行wait(),sleep(),join()时,一样会抛出InterruptedException,当然抛出后该线程的中断状态也会被系统复位。

1. sleep() &interrupt()

线程A正在使用sleep()暂停着: Thread.sleep(100000),如果要取消它的等待状态,可以在正在执行的线程里(比如这里是B)调用a.interrupt()[a是线程A对应到的Thread实例],令线程A放弃睡眠操作。即,在线程B中执行a.interrupt(),处于阻塞中的线程a将放弃睡眠操作。

当在sleep中时线程被调用interrupt()时,就马上会放弃暂停的状态并抛出InterruptedException。抛出异常的,是A线程。

2. wait() &interrupt()

线程A调用了wait()进入了等待状态,也可以用interrupt()取消。不过这时候要注意锁定的问题。线程在进入等待区,会把锁定解除,当对等待中的线程调用interrupt()时,会先重新获取锁定,再抛出异常。在获取锁定之前,是无法抛出异常的。

3. join() &interrupt()

当线程以join()等待其他线程结束时,当它被调用interrupt(),它与sleep()时一样,会马上跳到catch块里.。

注意,调用的interrupt()方法,一定是调用被阻塞线程的interrupt方法。如在线程a中调用线程t.interrupt()。

http://www.open-open.com/lib/view/open1417421714612.html

Java线程的生命周期(转)的更多相关文章

  1. 【Java并发基础】Java线程的生命周期

    前言 线程是操作系统中的一个概念,支持多线程的语言都是对OS中的线程进行了封装.要学好线程,就要搞清除它的生命周期,也就是生命周期各个节点的状态转换机制.不同的开发语言对操作系统中的线程进行了不同的封 ...

  2. Java线程的生命周期

    线程的生命周期包括:新建(New).就绪(Runnable).运行(Running).阻塞(Blocked)和死亡(Dead)5种状态.线程状态转换图如下: 1.新建状态(New) 当程序使用new关 ...

  3. 图解Java线程的生命周期,看完再也不怕面试官问了

    文章首发自个人微信公众号: 小哈学Java https://www.exception.site/java-concurrency/java-concurrency-thread-life-cycle ...

  4. java线程的生命周期及五种基本状态

    一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程各重要知识点.掌握了上图中的各知识点,Java中的多线程也就基本上掌 ...

  5. Java—线程的生命周期及线程控制方法详解

    线程生命周期5种状态 介绍   线程的生命周期经过新建(New).就绪(Runnable).运行(Running).阻塞(Bolocked)和死亡(Dead) 状态转换图 新建(New)   程序使用 ...

  6. Java线程之生命周期

    简述 以下类图展示了线程生命周期中不同的状态.我们可以创建一个线程并启动它,但是线程状态从Runnable.Running.Blocked等状态的变化取决于系统线程调度器,java本身并不能完全控制. ...

  7. Java 线程的生命周期

    当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(New).就绪(Runnable).运行(Running).阻塞(Blocked)和死 ...

  8. Java线程的生命周期与状态流转

    上图是一个线程的生命周期状态流转图,很清楚的描绘了一个线程从创建到终止的过程. 这些状态的枚举值都定义在java.lang.Thread.State下 NEW:毫无疑问表示的是刚创建的线程,还没有开始 ...

  9. 深入Java线程管理(二):线程的生命周期

    Java线程的生命周期 一个线程的产生是从我们调用了start方法开始进入Runnable状态,即可以被调度运行状态,并没有真正开始运行,调度器可以将CPU分配给它,使线程进入Running状态,真正 ...

随机推荐

  1. VS2010 安装 Boost 库 1.54

    Boost库被称为C++准标准库, 功能很是强大, 下面记录我在VS2010中安装使用Boost库的过程. 首先上官网http://www.boost.org/下载最新的Boost库, 我的版本是1_ ...

  2. 认识到了x64程序的必要性

    假如我做一个程序,在运行过程中需要使用一个Map,然而这个Map存储了超多信息的话,系统内存不够就会崩溃了.以前的解决方案可能是把内容存储在一个文件/数据库里,但是有内存岂不是更方便.更直截了当!

  3. Android开发之大位图二次採样压缩处理(源码分享)

    图片有各种形状和大小.在很多情况下这些图片是远远大于我们的用户界面(UI)且占领着极大的内存空间,假设我们不正确位图进行压缩处理,我们的程序会发生内存泄露的错误. MainActivity的代码 pa ...

  4. PHP $_SERVER

    $_SERVER 是一个包括了诸如头信息(header).路径(path).以及脚本位置(script locations)等等信息的数组.这个数组中的项目由 Web server创建.不能保证每一个 ...

  5. 服务确定(服务类收货ML81N)

    FUNCTION zrfc_mm005. *"---------------------------------------------------------------------- * ...

  6. 类似QtiPlot的veusz,sigmaplot,pymol

    qtiplot在win下没那么好编译 依赖很多外部包的 scidavis 和 labplot是从他fork出来的 比较接近Origin 可以用这两个 FreeBSD 的 ports 里有直接 cd / ...

  7. linux卸载不完全

    kali安装一个Nessus,但是在加载插件时候断网了,插件没下载完,后面打开也无法下载插件于是果断卸载了重装,但是无法删除配置文件,恼火了一天 完全卸载软件命令 sudo apt-get --pur ...

  8. 大容量XFS异常处理

    今天在检查报警的时候发现部分数据异常,登陆备份机查看文件状态的时候发现磁盘空间已经满了,inode也已经有问题了,因此先停掉了所有的备份进程,开始检查问题. 首先是磁盘空间满了,尝试删除部分文件,发现 ...

  9. webdynpro tree控件使用

    1.  首先创建一个TREE控件 2.  在Tree下面创建一个TREE  NODE  TYPE ,node type 是可以继续展开的,而Item type是无法展开的. 3. 创建node.,下面 ...

  10. HTML5 Canvas阴影用法演示

    HTML5 Canvas阴影用法演示 HTML5 Canvas中提供了设置阴影的四个属性值分别为: context.shadowColor = “red” 表示设置阴影颜色为红色 context.sh ...