Java线程的生命周期的详解

Java线程的生命周期的详解

对于多线程编程而言,理解线程的生命周期非常重要,本文就针对这一点进行讲解。

一、线程的状态

线程的存在有几种不同的状态,如下:

  • New状态
  • Ready状态
  • Running状态
  • Dead状态
  • Non Runnable状态

1、New状态

New状态是线程已经被创建,但是还未开始运行的状态。此状态通过调用线程的start()方法可让线程运行。

2、Runnable状态

Runnable状态可称为准备运行状态,也可称为队列,此状态通过调用线程的start()方法可让线程运行。
线程调度器决定要运行哪些线程,且线程运行多久。

3、Running状态

如果一个线程正在执行中,那么它处于Running状态。

4、Dead状态

一旦某个线程进入了Dead状态,那么它就再也不能运行了。

5、Non runnable状态

某个正在运行的线程可转变到Non runnable状态,这取决于运行情况。
某个线程还可以一直保持Non runnable状态,直到满足的条件出现。
某个Non runnable状态的线程不能直接跳转到运行状态,而是必须先转变为Runnable状态。
睡眠Sleeping:线程睡眠指定的时间。
I/O阻塞:线程等待,直到阻塞操作的完成。
join阻塞:线程等待,直到另一个线程执行完成。
等待通知:线程等待另一个线程的通知。
锁机制阻塞:线程等待,直到指定的锁被释放,获得锁。

Java虚拟机JVM根据线程的优先级和调度原则执行线程。

二、线程调度器

在JVM中,线程调度器的实现通常基于以下两种策略:

  • 抢占式调度策略
  • 分时调度策略或Round-robin循环调度策略

线程调度器的实现与平台无关,因此线程的调度是不可预测的。

三、线程的优先级

JVM会为每一个新创建的线程分配一个优先级。

  • 0级:这是最低的优先级
  • 5级:这是普通的优先级
  • 10级:这是最高的优先级

为了保存这些值,线程类有三个相应的变量:

  • public static final int MIN_PRIORITY
  • public static final int NORM_PRIORITY
  • public static final int MAX_PRIORITY

一个线程首先会继承其父线程的优先级,每一个线程默认的优先级是5级(Normal优先级),主线程的默认优先级为5级。

可以通过setPriority(int priority)方法来设置线程的优先级。

  • public final void setPriority(int priority)
  • public void getPriority();

用户定义的线程,其默认的线程名为Thread+序号,序号从0开始,比如第一个线程为Thread0。
线程名可以通过setName(String name)方法进行设置,可使用getName()方法获得线程的名字。

  • public final void setName(String name)
  • public final String getName().

实例

下面看一个例子:

package demo.ch;

public class UserThread extends Thread {
  UserThread() {
    super();
  }

  UserThread(String name) {
    super(name);
  }

  public void run() {
    System.out.println("thread started running..");
  }

  public static void main(String[] args) {
    UserThread thread1 = new UserThread("Thread1");
    UserThread thread2 = new UserThread("Thread2");

    System.out.println("Thread 1 initial name and priority");
    System.out.println("name:" + thread1.getName());
    System.out.println("priority:" + thread1.getPriority());

    System.out.println("Thread 2 initial name and priority");
    System.out.println("name:" + thread2.getName());
    System.out.println("priority:" + thread2.getPriority());
    System.out.println("");

    thread1.setPriority(6);
    thread2.setPriority(9);

    System.out.println("Thread 1 initial name and priority");
    System.out.println("name:" + thread1.getName());
    System.out.println("priority:" + thread1.getPriority());

    System.out.println("Thread 2 initial name and priority");
    System.out.println("name:" + thread2.getName());
    System.out.println("priority:" + thread2.getPriority());
    System.out.println("");

    thread1.start();
    thread2.start();

    for(int i=0; i<5; i++)
      System.out.println("main method i value: " + i);
  }
}

输出结果:

Thread 1 initial name and priority
name:Thread1
priority:5
Thread 2 initial name and priority
name:Thread2
priority:5

Thread 1 initial name and priority
name:Thread1
priority:6
Thread 2 initial name and priority
name:Thread2
priority:9

main method i value: 0
main method i value: 1
thread started running..
main method i value: 2
thread started running..
main method i value: 3
main method i value: 4

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • java多线程编程之线程的生命周期

    复制代码 代码如下: // 开始线程public void start( );public void run( ); // 挂起和唤醒线程public void resume( ); // 不建议使用public void suspend( );// 不建议使用public static void sleep(long millis);public static void sleep(long millis, int nanos); // 终止线程public void stop( );   /

  • java线程之线程的生命周期的使用

    与人有生老病死一样,线程也同样要经历开始(等待).运行.挂起和停止四种不同的状态.这四种状态都可以通过Thread类中的方法进行控制.下面给出了Thread类中和这四种状态相关的方法. 复制代码 代码如下: // 开始线程     public void start( );     public void run( ); // 挂起和唤醒线程     public void resume( );     // 不建议使用     public void suspend( );    // 不建议

  • 初步学习Java中线程的实现与生命周期

    线程的实现 在Java中通过run方法为线程指明要完成的任务,有两种技术来为线程提供run方法: 1.继承Thread类并重写它的run方法.之后创建这个子类的对象并调用start()方法. 2.通过定义实现Runnable接口的类进而实现run方法.这个类的对象在创建Thread的时候作为参数被传入,然后调用start()方法. Thread类是专门用来创建线程和对线程进行操作的类.当某个类继承了Thread类之后,该类就叫做一个线程类. 两种方法均需执行线程的start()方法为线程分配必须

  • Java 线程的生命周期详细介绍及实例代码

    当线程被创建并启动之后,它既不是一启动就进入执行状态,也不是一直处于执行状态,在其生命周期中,要经过"新建(New)"."就绪(Runnable)"."运行(Running')"."阻塞(Blocked)"和"死亡(Dead)"五种状态.线程在创建之后,不可能一直霸占着CPU独立运行,需要在多个线程之间切换,所以大部分时间处于运行.阻塞之间切换.  一.线程的状态 线程的存在有几种不同的状态,如下: New

  • 图解Java线程的生命周期

    在Java中,线程有5中不同状态,分别是:新建(New).就绪(Runable).运行(Running).阻塞(Blocked)和死亡(Dead).它们之间的转换图如下: 上图有一个例外,调用yield()方法可以让当前处于运行状态的线程转入就绪状态.如果要测试某线程是否已经死亡,可以使用isAlive()方法,该方法在线程处于就绪.运行.阻塞时放回true,新建和死亡时返回false.不要试图对一个已经死亡的线程调用start()方法而重新启动,死亡就是死亡和人一样,不可能再生.还有也不要对一

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

    一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable). 注意:不能对已经启动的线程再次调用start()方法,否则会出现Javalang.IllegalThreadStateException异常. 2.就绪状态 处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(尽管是采用队列形式,事实上,把它称

  • java 线程的生命周期详解

    一个线程的生命周期: 新建状态: 使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态.它保持这个状态直到程序 start() 这个线程. 就绪状态: 当线程对象调用了start()方法之后,该线程就进入就绪状态.就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度. 运行状态: 如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态.处于运行状态的线程最为复杂,它可以变为阻塞状态.就绪状态和死亡状态. 阻塞状态: 如

  • Java线程的生命周期的详解

    Java线程的生命周期的详解 对于多线程编程而言,理解线程的生命周期非常重要,本文就针对这一点进行讲解. 一.线程的状态 线程的存在有几种不同的状态,如下: New状态 Ready状态 Running状态 Dead状态 Non Runnable状态 1.New状态 New状态是线程已经被创建,但是还未开始运行的状态.此状态通过调用线程的start()方法可让线程运行. 2.Runnable状态 Runnable状态可称为准备运行状态,也可称为队列,此状态通过调用线程的start()方法可让线程运

  • Android bindService的使用与Service生命周期案例详解

    Android中有两种主要方式使用Service,通过调用Context的startService方法或调用Context的bindService方法,本文只探讨纯bindService的使用,不涉及任何startService方法调用的情况.如果想了解startService相关的使用,请参见<Android中startService的使用及Service生命周期>. bindService启动服务的特点 相比于用startService启动的Service,bindService启动的服务

  • 基于java 线程的几种状态(详解)

    线程可以有六种状态: 1.New(新创建) 2.Runnable(可运行)(运行) 3.Blocked(被阻塞) 4.Waiting(等待) 5.Timed waiting(计时等待) 6.Terminated(被终止) 新创建线程: 当用new操作符创建一个新线程时,如new Thread(r),该线程还没有开始运行,它的当前状态为new,在线程运行之前还有一些基础工作要做. 可运行线程: 一旦线程调用start方法,线程处于runnable状态.在这个状态下的线程可能正在运行也可能没有运行(

  • Java线程池FutureTask实现原理详解

    前言 线程池可以并发执行多个任务,有些时候,我们可能想要跟踪任务的执行结果,甚至在一定时间内,如果任务没有执行完成,我们可能还想要取消任务的执行,为了支持这一特性,ThreadPoolExecutor提供了 FutureTask 用于追踪任务的执行和取消.本篇介绍FutureTask的实现原理. 类视图 为了更好的理解FutureTask的实现原理,这里先提供几个重要接口和类的结构,如下图所示: RunnableAdapter ThreadPoolExecutor提供了submit接口用于提交任

  • Java 线程的生命周期完整实例分析

    本文实例讲述了Java 线程的生命周期.分享给大家供大家参考,具体如下: 一 代码 /** * @Title: ThreadStatus.java * @Description: TODO(演示线程的生命状态) */ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.TimeUnit; public class T

  • Java线程三种命名方法详解

    这篇文章主要介绍了Java线程三种命名方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.实例化一个线程对象 Thread t = new Thread(); t.setName("甲"); 2.实例化一个线程对象的同时,通过构造方法对线程进行命名 Thread(Runnable r, String name) Thread t = new Thread(() -> {}, "甲"); 3.使用自定义

  • Vue生命周期区别详解

    生命周期分类 vue每个组件都是独立的,每个组件都有一个属于它的生命周期, 从一个组件创建.数据初始化.挂载.更新.销毁,这就是一个组件所谓的生命周期. 在组件中具体的方法有: beforeCreate created beforeMount mounted beforeUpdate updated beforeDestroy destroyed beforeCreate( 创建前 ) 在实例初始化之后,数据观测和事件配置之前被调用,此时组件的选项对象还未创建,el 和 data 并未初始化,因

  • Java 线程的优先级(setPriority)案例详解

    线程可以划分优先级,优先级高的线程得到的CPU资源比较多,也就是CPU优先执行优先级高的线程对象中的任务. 设置线程优先级有助于帮助线程规划器确定下一次选中哪一个线程优先执行. java中优先级分为1-10个级别 线程优先级的继承特性 例如a线程启迪b线程,则b线程的优先级与a的一样. 代码说话:(很简单) public class MyThread1 extends Thread { @Override public void run() { System.out.println("MyThr

  • Java 线程池全面总结与详解

    目录 原理 阻塞队列 有界阻塞队列 无界阻塞队列 同步移交队列 实现类分析 使用Executors创建线程池 线程池关闭 线程池是很常用的并发框架,几乎所有需要异步和并发处理任务的程序都可用到线程池. 使用线程池的好处如下: 降低资源消耗:可重复利用已创建的线程池,降低创建和销毁带来的消耗: 提高响应速度:任务到达时,可立即执行,无需等待线程创建: 提高线程的可管理性:线程池可对线程统一分配.调优和监控. 原理 线程池的原理非常简单,这里用处理流程来概括: 线程池判断核心池里的线程是否都在执行任

  • java线程池ThreadPoolExecutor类使用详解

    在<阿里巴巴java开发手册>中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量:另一方面线程的细节管理交给线程池处理,优化了资源的开销.而线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式,这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool().newSingleThreadExecutor().newCachedThreadPool(

随机推荐