• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > Java线程的生命周期和状态控制_动力节点Java学院整理

Java线程的生命周期和状态控制_动力节点Java学院整理

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了java线程的生命周期,java中线程的生命周期,java多线程生命周期,java线程周期,java线程等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

一、线程的生命周期

线程状态转换图:

/UpFiles/2017/5/28/2017519161148128.png?2017419161216

1、新建状态

用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)。

注意:不能对已经启动的线程再次调用start()方法,否则会出现Javalang.IllegalThreadStateException异常。

2、就绪状态

处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(尽管是采用队列形式,事实上,把它称为可运行池而不是可运行队列。因为cpu的调度不一定是按照先进先出的顺序来调度的),等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为“cpu调度”。一旦获得CPU,线程就进入运行状态并自动调用自己的run方法。

提示:如果希望子线程调用start()方法后立即执行,可以使用Thread.sleep()方式使主线程睡眠一伙儿,转去执行子线程。

3、运行状态

处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。处于就绪状态的线程,如果获得了cpu的调度,就会从就绪状态变为运行状态,执行run()方法中的任务。如果该线程失去了cpu资源,就会又从运行状态变为就绪状态。重新等待系统分配资源。也可以对在运行状态的线程调用yield()方法,它就会让出cpu资源,再次变为就绪状态。

当发生如下情况是,线程会从运行状态变为阻塞状态:

①、线程调用sleep方法主动放弃所占用的系统资源

②、线程调用一个阻塞式IO方法,在该方法返回之前,该线程被阻塞

③、线程试图获得一个同步监视器,但更改同步监视器正被其他线程所持有

④、线程在等待某个通知(notify)

⑤、程序调用了线程的suspend方法将线程挂起。不过该方法容易导致死锁,所以程序应该尽量避免使用该方法。

当线程的run()方法执行完,或者被强制性地终止,例如出现异常,或者调用了stop()、desyory()方法等等,就会从运行状态转变为死亡状态。

4、阻塞状态

处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。
在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。

5、死亡状态

当线程的run()方法执行完,或者被强制性地终止,就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。 如果在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。

二、线程状态的控制

Java提供了一些便捷的方法用于会线程状态的控制。

 /UpFiles/2017/5/28/2017519161258135.png?2017419161311.

可以看到很多方法,已经标注为过时的,我们应该尽可能的避免使用它们,而应该重点关注start()、interrupt()、join()、sleep()、yield()等直接控制方法,和setDaemon()、setPriority()等间接控制方法。

1、线程睡眠——sleep

如果我们需要让当前正在执行的线程暂停一段时间,并进入阻塞状态,则可以通过调用Thread的sleep方法,从上面可以看到sleep方法有两种重载的形式,但是使用方法一样。

比如,我们想要使主线程每休眠100毫秒,然后再打印出数字:

 public class Test { 
  public static void main(String[] args) throws InterruptedException { 
   for(int i=;i<;i++){ 
    System.out.println("main"+i); 
    Thread.sleep(); 
   } 
  } 
 }
</div>

可以明显看到打印的数字在时间上有些许的间隔。

注意如下几点问题

①、sleep是静态方法,最好不要用Thread的实例对象调用它,因为它睡眠的始终是当前正在运行的线程,而不是调用它的线程对象,它只对正在运行状态的线程对象有效。看下面的例子:

public class Test1 { 
  public static void main(String[] args) throws InterruptedException { 
   System.out.println(Thread.currentThread().getName()); 
   MyThread myThread=new MyThread(); 
   myThread.start(); 
   myThread.sleep(1000);//这里sleep的就是main线程,而非myThread线程 
   Thread.sleep(10); 
   for(int i=0;i<100;i++){ 
    System.out.println("main"+i); 
   } 
  } 
 } 
</div>

②、Java线程调度是Java多线程的核心,只有良好的调度,才能充分发挥系统的性能,提高程序的执行效率。但是不管程序员怎么编写调度,只能最大限度的影响线程执行的次序,而不能做到精准控制。因为使用sleep方法之后,线程是进入阻塞状态的,只有当睡眠的时间结束,才会重新进入到就绪状态,而就绪状态进入到运行状态,是由系统控制的,我们不可能精准的去干涉它,所以如果调用Thread.sleep(1000)使得线程睡眠1秒,可能结果会大于1秒。

public class Test1 { 
public static void main(String[] args) throws InterruptedException { 
   new MyThread().start(); 
new MyThread().start(); 
  } 
 }  
 class MyThread extends Thread { 
  @Override 
  public void run() { 
   for (int i = 0; i < 3; i++) { 
    System.out.println(this.getName()+"线程" + i + "次执行!"); 
    try { 
     Thread.sleep(50); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
   } 
  } 
 } 
</div>

看某一次的运行结果:

1. Thread-0线程0次执行! 
2. Thread-1线程0次执行! 
3. Thread-1线程1次执行! 
4. Thread-0线程1次执行! 
5. Thread-0线程2次执行! 
6. Thread-1线程2次执行! 

可以看到,线程0首先执行,然后线程1执行一次,又了执行一次。可以看到它并不是按照sleep的顺序执行的。

2、线程让步——yield

yield()方法和sleep()方法有点相似,它也是Thread类提供的一个静态的方法,它也可以让当前正在执行的线程暂停,让出cpu资源给其他的线程。但是和sleep()方法不同的是,它不会进入到阻塞状态,而是进入到就绪状态。yield()方法只是让当前线程暂停一下,重新进入就绪的线程池中,让系统的线程调度器重新调度器重新调度一次,完全可能出现这样的情况:当某个线程调用yield()方法之后,线程调度器又将其调度出来重新进入到运行状态执行。

实际上,当某个线程调用了yield()方法暂停之后,优先级与当前线程相同,或者优先级比当前线程更高的就绪状态的线程更有可能获得执行的机会,当然,只是有可能,因为我们不可能精确的干涉cpu调度线程。

yield的用法:

public class Test1 { 
  public static void main(String[] args) throws InterruptedException { 
   new MyThread("低级", 1).start(); 
   new MyThread("中级", 5).start(); 
   new MyThread("高级", 10).start(); 
  } 
 } 
 class MyThread extends Thread { 
  public MyThread(String name, int pro) { 
   super(name);// 设置线程的名称 
   this.setPriority(pro);// 设置优先级 
  } 
  @Override 
  public void run() { 
   for (int i = 0; i < 30; i++) { 
    System.out.println(this.getName() + "线程第" + i + "次执行!"); 
   if (i % 5 == 0) 
     Thread.yield(); 
   } 
  } 
 } 
</div>

关于sleep()方法和yield()方的区别如下:

①、sleep方法暂停当前线程后,会进入阻塞状态,只有当睡眠时间到了,才会转入就绪状态。而yield方法调用后 ,是直接进入就绪状态,所以有可能刚进入就绪状态,又被调度到运行状态。

②、sleep方法声明抛出了InterruptedException,所以调用sleep方法的时候要捕获该异常,或者显示声明抛出该异常。而yield方法则没有声明抛出任务异常。

③、sl

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Java线程的生命周期和状态控制_动力节点Java学院整理
  • Java线程的生命周期和状态控制_动力节点Java学院整理

相关文章

  • 2017-05-28Java 反射机制详解及实例
  • 2017-05-28Java 多线程并发编程_动力节点Java学院整理
  • 2017-05-28详解Java从后台重定向(redirect)到另一个项目的方法
  • 2017-05-28java基础中异常及包归纳整理
  • 2017-05-28java数据结构与算法之简单选择排序详解
  • 2017-08-27java 中StringBuffer中常用的方法
  • 2017-05-28Java基本数据类型与对应的包装类(动力节点java学院整理)
  • 2017-05-28Java 网络编程socket编程等详解
  • 2017-05-28Spring集成Struts与Hibernate入门详解
  • 2017-05-28java 开发中网络编程之IP、URL详解及实例代码

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Java中IO流 字节流实例详解
    • java读取txt文件代码片段
    • 基于Java的正则表达式
    • 详解Java回调的原理与实现
    • Java Object类详解_动力节点Java学院整理
    • 解决Java原生压缩组件不支持中文文件名乱码的问题
    • Spring配置多个数据源并实现动态切换示例
    • Java Socket编程(一) Socket传输模式
    • Java中Object toString方法简介_动力节点Java学院整理
    • java 中继承和多态详细介绍

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有