iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java线程生命周期的终止与复位
  • 212
分享到

Java线程生命周期的终止与复位

2024-04-02 19:04:59 212人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录Thread生命周期生命周期概述线程生命周期流程图线程生命周期测试启动线程java中的启动Hotspot中的启动线程中断与复位不要使用stop方法使用interrupt方法线程的

Thread生命周期

生命周期概述

Java的线程状态描述放在Thread类里面的枚举类State中.总共包含了6中状态(从出生到死亡)。

public enum State {
    
    NEW,

    
    RUNNABLE,

    
    BLOCKED,

    
    WaiTING,

    
    TIMED_WAITING,

    
    TERMINATED;
}

线程生命周期流程图

线程生命周期测试

public class ThreadStatusDemo {
    public static void main(String[] args) throws InterruptedException {
        // 测试 NEW RUNNABLE TERMINATED
        Thread terminated_thread = new Thread(() -> {
            long start = System.currentTimeMillis();
            // 运行三秒 ,打印TERMINATED_THREAD线程runnable状态
            while (System.currentTimeMillis()-start<3000){}
        }, "TERMINATED_THREAD");
        // NEW
        Thread.State state = terminated_thread.getState();
        System.out.println(terminated_thread.getName()+" :state = " + state);

        terminated_thread.start();
        TimeUnit.SECONDS.sleep(1);
        // RUNNABLE
        Thread.State state1 = terminated_thread.getState();
        System.out.println(terminated_thread.getName()+"state1 = " + state1);

        TimeUnit.SECONDS.sleep(5);
        Thread.State state2 = terminated_thread.getState();
        // TERMINATED
        System.out.println(terminated_thread.getName()+"state2 = " + state2);

        // RUNNABLE
        new Thread(() -> {
            while (true) {

            }
        }, "Runnle_Thread").start();
        // TIMED_WAITING
        new Thread(() -> {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Time_Waiting_Thread").start();
        // WAITING
        new Thread(() -> {
            while (true) {
                synchronized (ThreadStatusDemo.class) {
                    try {
                        ThreadStatusDemo.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "Waiting_Thread").start();

        // 这两个看谁先抢占到cpu获得,另一个就blocked
        // timed_waiting
        new Thread(new BlockedDemo(), "Blocke01_Thread").start();
        // blocked
        new Thread(new BlockedDemo(), "Blocke02_Thread").start();
    }
    static class BlockedDemo extends Thread {
        @Override
        public void run() {
            synchronized (BlockedDemo.class) {
                while (true) {
                    try {
                        TimeUnit.SECONDS.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

启动线程

java中的启动

Java启动一个线程调用start方法,start方法内部调用了 start0()native方法。

public synchronized void start() {
    . . .
    boolean started = false;
    try { 
        // 调用native方法
        start0();
        started = true;
    } finally {
        try {
            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {
            
        }
    }
}

这个测试是为了验证上图的正确性,只贴了部分.

Hotspot中的启动

查看指引:

 在JVM.cpp找到JVM_StartThread方法。发现是先创建个 JavaThread作为本地线程然后启动这个本地线程(借助os【thread.cpp】,因为jvm是跨平台的,这里是以linux-os为示例)

JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
  JVMWrapper("JVM_StartThread");
  JavaThread *native_thread = NULL;
  bool throw_illegal_thread_state = false;
  {
    MutexLocker mu(Threads_lock);

    if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {
      throw_illegal_thread_state = true;
    } else {
      jlong size =
             java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));
      size_t sz = size > 0 ? (size_t) size : 0;
      // 先创建一个JavaThread
      native_thread = new JavaThread(&thread_entry, sz);
      if (native_thread->osthread() != NULL) {
        native_thread->prepare(jthread);
      }
    }
  }
  if (throw_illegal_thread_state) {
    THROW(vmSymbols::java_lang_IllegalThreadStateException());
  }
  assert(native_thread != NULL, "Starting null thread?");
  if (native_thread->osthread() == NULL) {
    delete native_thread;
    if (JvmtiExport::should_post_resource_exhausted()) {
      JvmtiExport::post_resource_exhausted(
        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS,
        "unable to create new native thread");
    }
    THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),
              "unable to create new native thread");
  }
  // 然后启动这个本地线程 thread.cpp
  Thread::start(native_thread);
JVM_END

JavaThread 创建线程:

JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
  Thread()
#if INCLUDE_ALL_GCS
  , _satb_mark_queue(&_satb_mark_queue_set),
  _dirty_card_queue(&_dirty_card_queue_set)
#endif // INCLUDE_ALL_GCS
{
  if (TraceThreadEvents) {
    tty->print_cr("creating thread %p", this);
  }
  initialize();
  _jni_attach_state = _not_attaching_via_jni;
  set_entry_point(entry_point);
  os::ThreadType thr_type = os::java_thread;
  thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :
                                                     os::java_thread
// 调用os(操作系统)创建个线程
  os::create_thread(this, thr_type, stack_sz);
  _safepoint_visible = false;
   . . .
}

thread.cpp 启动线程:

// tips: 启动线程的方法
void Thread::start(Thread* thread) {
  trace("start", thread);
  // Start is different from resume in that its safety is guaranteed by context or
  // being called from a Java method synchronized on the Thread object.
  if (!DisableStartThread) {
    if (thread->is_Java_thread()) {
      // Initialize the thread state to RUNNABLE before starting this thread.
      // Can not set it after the thread started because we do not know the
      // exact thread state at that time. It could be in MONITOR_WAIT or
      // in SLEEPING or some other state.
      // tips:启动之后设置线程的状态为 可运行状态 RUNNABLE
      java_lang_Thread::set_thread_status(((JavaThread*)thread)->threadObj(),
                                          java_lang_Thread::RUNNABLE);
    }
    // 借助操作系统启动线程
    os::start_thread(thread);
  }
}

线程中断与复位

不要使用stop方法

线程的终止不要简单的调用 stop方法,这个方法和其他的线程控制方法(suspend,resume)一样都是过期了不建议使用的,这些方法都是不安全的。 例如stop()方法在结束一个线程的时候并不保证线程资源的正常释放,因此可能导致出现一些不确定的状态。 按照人类逻辑来理解:T1线程调用方法修改T2线程的状态,但是T2现在在做什么T1是不清楚的,所以强制他关闭就是不安全的,就好比在Linux中使用 kill -9 杀掉一个进程。

使用interrupt方法

interrupt()方法只是修改了被中断线程的中断标志 ,并没有做什么过分的事儿。就像平时写代码的时候修改某对象的标志,对象自己通过标志类决定执行什么逻辑。这里也是一样,interrupt()方法修改中断标志,被中断的线程,自己决定做什么事儿(中断或者不中断都是被中断线程自己决定的,外部只是通知他,不是强迫他)。追一下源码

1.Java调用interrupt方法 

2.通过指引找到 jvm.cpp#JVM_Interrupt方法

thread.cpp interrupt 借用操作系统。直接通过系统调用 interrupt
void Thread::interrupt(Thread* thread) {
  trace("interrupt", thread);
  debug_only(check_for_dangling_thread_pointer(thread);)
  // tips: 调用操作系统的interrupt方法
  os::interrupt(thread);
}

这里还是以os_linux.cpp为例最终调用osthread的set_interrupted修改状态 

这里就印证了上方的 Thread.interrupt()只是修改了线程的一个标志位 ,并没有做什么过分的事儿。

线程的复位

interruptedisInterrupted

这两个放在一起是因为他们底层都是调用的同一个native方法isInterrupted()只是给了不同的入参。 再就是,有过面试官问到他两的区别,所以干脆放在一起。首先说结论 ,isInterrupted()会返回线程的中断状态,interrupted()不仅会返回中断状态,而且如果线程处于状态状态还会将线程终端状态复位(清除中断状态)。

os_linux.cpp的is_interrupted()方法印证了上面说的isInterrupted()会返回线程的中断状态,interrupted()不仅会返回中断状态,而且如果线程处于状态状态还会将线程终端状态复位(清除中断状态)。

其他的线程复位

Java中只要抛出了InnterruptException异常的方法都对线程进行了复位。先理顺下为什么要这么做:查看下基本上抛出InnterruptException异常的方法都是线程阻塞方法,比如sleep(),wait(),join()。这类方法执行后线程会处于TIMED_WAITING或者WAITING状态,处于这类状态的线程是不受控的(线程丧失了对自己的主导,需要其他的线程唤醒,或者阻塞时间到达才能拥有自己的主导权),这个时候线程中断,线程自己却没办法处理。甚至可能永远等不到释放而无法执行中断。所以,在线程是中断状态下,执行方法让线程阻塞,就要抛出一个异常告诉外界 ,我现在是阻塞状态,并且将中断标记复位,方便外界进行处理(例如中断线程的执行或者继续阻塞方法),相当于给了外界一个改变线程状态的入口。 以sleep()为例追踪下源码:

通过指引找到 jcm.cpp#JVM_Sleep

方法入口就直接判断线程的中断状态了 ,is_interrupted()上面介绍过了,参数为true就是清除中断标志并且返回清除之前的中断状态。这里线程是中断状态的就直接抛出 InnterruptException sleep interrupted异常了。

到此这篇关于Java线程生命周期的终止与复位的文章就介绍到这了,更多相关Java线程生命周期内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java线程生命周期的终止与复位

本文链接: https://www.lsjlt.com/news/153297.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java线程生命周期的终止与复位
    目录Thread生命周期生命周期概述线程生命周期流程图线程生命周期测试启动线程java中的启动Hotspot中的启动线程中断与复位不要使用stop方法使用interrupt方法线程的...
    99+
    2024-04-02
  • Java线程生命周期的终止与复位怎么实现
    这篇文章主要介绍“Java线程生命周期的终止与复位怎么实现”,在日常操作中,相信很多人在Java线程生命周期的终止与复位怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java线程生命周期的终止与复位怎...
    99+
    2023-07-02
  • Java线程的生命周期的详解
    Java线程的生命周期的详解对于多线程编程而言,理解线程的生命周期非常重要,本文就针对这一点进行讲解。一、线程的状态线程的存在有几种不同的状态,如下: New状态 Ready状态 Running状态 Dead状态 Non Runn...
    99+
    2023-05-30
    java 线程 生命周期
  • 深入探究Java线程的状态与生命周期
    目录一、线程的状态新建(初始)就绪(可运行)运行阻塞死亡二、线程的状态转移三、线程的生命周期一、线程的状态 NEW: 安排了工作, 还未开始行动RUNNABLE: 可工作的. 又可...
    99+
    2024-04-02
  • Java中线程的生命周期是什么
    这篇文章主要介绍“ Java中线程的生命周期是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“ Java中线程的生命周期是什么”文章能帮助大家解决问题。操作系统中线程的生命周期操作系统的线程生命周...
    99+
    2023-06-16
  • java线程生命周期哪些状态
    Java线程生命周期有以下几个状态:1. 新建状态(New):线程被创建但还未开始执行。2. 就绪状态(Runnable):线程已经...
    99+
    2023-08-26
    java
  • 如何理解Java线程生命周期
    本篇内容主要讲解“如何理解Java线程生命周期”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何理解Java线程生命周期”吧!如果要说 Java 线程的生命周期的话,那我觉得就要先说说操作系统的...
    99+
    2023-06-16
  • 怎么理解java线程生命周期
    本篇内容主要讲解“怎么理解java线程生命周期”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么理解java线程生命周期”吧!线程生命周期的几种状态刚接触线程生命周期时,我总是记不住,也理解不了...
    99+
    2023-06-16
  • Java线程生命周期及转换过程
    目录Java 线程生命周期生命周期转换1.从 NEW 到 RUNNABLE2.从 RUNNABLE 到 BLOCKED3.从 RUNNABLE 到 WAITTING4.从 RUNNA...
    99+
    2024-04-02
  • Java线程的6种状态与生命周期是什么
    本文小编为大家详细介绍“Java线程的6种状态与生命周期是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java线程的6种状态与生命周期是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1.线程状态(生命...
    99+
    2023-06-30
  • Java多线程 - 定时器-并发与并行-线程生命周期
    文章目录 多线程补充定时器并发和并行线程的生命周期 多线程补充 定时器 定时器介绍: 定时器是一种控制任务延时调用,或者周期调用的技术。 作用:闹钟、定时邮件发送。 定时...
    99+
    2023-09-25
    java jvm 开发语言
  • Java中的线程生命周期核心概念
    目录Java多线程Java中线程的生命周期NEWRunnableBlockedWaitingTimed WaitingTerminated结论前言: 在本文中,我们将详细讨论Java...
    99+
    2024-04-02
  • 一文详解Java线程的6种状态与生命周期
    目录1.线程状态(生命周期)2.操作线程状态2.1.新创建状态(NEW)2.2.可运行状态(RUNNABLE)2.3.被阻塞状态(BLOCKED)2.4.等待唤醒状态(WAITING...
    99+
    2024-04-02
  • java线程生命周期的状态有哪几种
    Java线程的生命周期有以下几种状态:1. 新建(New):当线程对象被创建时,该线程处于新建状态。2. 就绪(Runnable):...
    99+
    2023-09-11
    java
  • java项目中线程的生命周期有哪些
    本篇文章为大家展示了java项目中线程的生命周期有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一个线程的生命周期:新建状态: 使用 new 关键字和 Thread 类或其子类建立一个线程对象后...
    99+
    2023-05-31
    java 线程 生命周期
  • Java线程生命周期图文详细讲解
    线程的状态 New 表示线程已创建,没启动的状态此时已经做了一些准备工作,还没有执行run方法中代码 Runnable 调用start方法之后的状态,表示可运行状态(不一定正在运行...
    99+
    2023-01-28
    Java线程生命周期 Java生命周期
  • Golang协程的创建与生命周期
    协程是一种轻量级线程,通过显式切换在同一调用栈复用执行单元。其生命周期包括创建、执行、挂起、恢复和完成。创建协程使用 go 关键字,实战中可用于并行计算(如计算斐波那契数列)。 Gol...
    99+
    2024-04-15
    生命周期 协程 golang
  • Java中Servlet的生命周期
    目录init()service()doGet()doPost()destroy() 方法架构Servlet从创建直到毁灭的整个过程: Servlet 初始化后调用 init () 方...
    99+
    2024-04-02
  • 微信小程序中的生命周期与生命周期函数浅析介绍
    目录一、生命周期概念分类二、生命周期函数概念作用分类三、总结一、生命周期 概念 生命周期(Life Cycle)是指一个对象从创建-->运行-->销毁的整个阶段 小程序的...
    99+
    2022-11-13
    微信小程序生命周期 微信小程序生命周期函数
  • Java中的线程生命周期核心概念是什么
    本篇内容主要讲解“Java中的线程生命周期核心概念是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中的线程生命周期核心概念是什么”吧!Java多线程在Java语言中,多线程是由线程的...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作