线程的start方法解析
Thread是学习我们学习多线程接触到的第一个有关多线程的类,相信每一个学习过或者了解过Java多线程的小伙伴都知道Thread类。这次分享主要对Thread的start方法进行讲解。
相信大家都知道,start方法是启动一个线程,并且该线程进入了可执行状态。在实际的编码中,我们是重写run()方法,调用start()方法启动线程,那么run()和start()方法有什么联系呢?下面我们就详细说说。
一、源码分析
首先我们查看start的源码,如下:
/** * Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread. * <p> * The result is that two threads are running concurrently: the * current thread (which returns from the call to the * <code>start</code> method) and the other thread (which executes its * <code>run</code> method). * <p> * It is never legal to start a thread more than once. * In particular, a thread may not be restarted once it has completed * execution. * * @exception IllegalThreadStateException if the thread was already * started. * @see #run() * @see #stop() */ public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }
start()方法是非常简单的,如果从上面单独看上面源码是看不出任何端倪的,不过我们可以看出来Thread被创建之后,threadStatus这个内部属性的值是0 。在上面源码中,最核心的部分就是start0();这个本地方法,也就是我们经常能在其他博文中看到的JNI方法,所谓JNI方法其实没有那么高大上,其实JNI就是Java平台用于和本地C代码进行互操作的API,JNI不支持Java类和 C++类之间的任何映射机制,这里只是简单的提一句。为什么说start0();是最核心的部分呢?看下图:
那么我们重写的run方法是何时被调用的呢?可以看start方法的注释,如下图:
Causes this thread to begin execution; the Java Virtual Machine calls the <code>run</code> method of this thread.
这段注释是说:在开始执行这个线程时,JVM就会调用run方法,也就是说run方法就是被JNI方法start0调用的。
通过源码总结要点:
-
Thread被构建后的NEW状态下,threadStatus这个内部属性值为0;
-
不能两次启动Thread,不然就会出现IllegalThreadStateException异常;
-
group.threadStartFailed(this);可以看出线程启动后将会被加入到一个ThreadGroup中;
-
一个线程生命周期到了TERMINATED状态,是不允许调用start方法的。
总结:jdk对start和run的设计,其实就是一个典型的模板模式,也就是父类编写算法结构代码,具体的逻辑实现由子类去完成。
原文地址:https://www.cnblogs.com/winqi/p/11403013.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【Java】07 常见 API
- 【Java】04 数组
- hadoop分布式格式化时出现异常java.net.unknownhostexception
- 【Java】05 面向对象
- 【Java】08 集合
- PAT (Advanced Level) Practice 1001 A B Format (20 分)
- 【Java】09 List 集合与 Collections 工具类
- PAT (Advanced Level) Practice 1003 Emergency (25 分)
- 数据结构严书习题6.65已知前中序,求二叉链表
- 【Java】10 Deque 接口
- 12.深入k8s:kubelet创建pod流程源码分析
- (较为详细)树的遍历方式一览(附完整源码可在VScode与cb运行)
- 【Java】12 Map 集合
- 【Java】11 Set 集合
- 4.表格-HTML基础