这篇文章作为Thread类源码剖析的补充,从一个侧面来看Thread源码。也解答了面试高频问题:“多次start一个线程会怎么样?”

答案是:java.lang.IllegalThreadStateException   线程状态非法异常   继承关系是:--->extends IllegalArgumentException--->extends RuntimeException一个运行时异常,下面我们从源码来透彻分析一下start()时做了什么。

 1 /**2      * Causes this thread to begin execution; the Java Virtual Machine3      * calls the <code>run</code> method of this thread.4      * <p>线程被执行,JVM调用run方法5      * The result is that two threads are running concurrently: the6      * current thread (which returns from the call to the7      * <code>start</code> method) and the other thread (which executes its8      * <code>run</code> method).9      * <p>
10      * It is never legal to start a thread more than once.多次调用start方法启动一个线程是非法的
11      * In particular, a thread may not be restarted once it has completed
12      * execution.
13      *
14      * @exception  IllegalThreadStateException  if the thread was already已经启动的线程再次start,异常
15      *               started.
16      * @see        #run()
17      * @see        #stop()
18      */
19     public synchronized void start() {
20         /**
21          * This method is not invoked for the main method thread or "system"
22          * group threads created/set up by the VM. Any new functionality added
23          * to this method in the future may have to also be added to the VM.
24          *
25          * A zero status value corresponds to state "NEW".
26          */
27         if (threadStatus != 0)//状态校验  0:NEW 新建状态
28             throw new IllegalThreadStateException();
29
30         /* Notify the group that this thread is about to be started
31          * so that it can be added to the group's list of threads
32          * and the group's unstarted count can be decremented. */
33         group.add(this);//添加进线程组
34
35         boolean started = false;
36         try {
37             start0();//调用native方法执行线程run方法
38             started = true;
39         } finally {
40             try {
41                 if (!started) {
42                     group.threadStartFailed(this);//启动失败,从线程组中移除当前前程。
43                 }
44             } catch (Throwable ignore) {
45                 /* do nothing. If start0 threw a Throwable then
46                   it will be passed up the call stack */
47             }
48         }
49     }
50
51     private native void start0();

greop.add(this),把当前线程添加进线程组,源码如下:

 1 /**2      * Adds the specified thread to this thread group.3      *4      * <p> Note: This method is called from both library code5      * and the Virtual Machine. It is called from VM to add6      * certain system threads to the system thread group.7      *8      * @param  t9      *         the Thread to be added
10      *
11      * @throws  IllegalThreadStateException
12      *          if the Thread group has been destroyed
13      */
14     void add(Thread t) {
15         synchronized (this) {
16             if (destroyed) {//线程组状态校验
17                 throw new IllegalThreadStateException();
18             }
19             if (threads == null) {
20                 threads = new Thread[4];//初始化长度为4的Thread数组
21             } else if (nthreads == threads.length) {//数组满了就扩容2倍
22                 threads = Arrays.copyOf(threads, nthreads * 2);
23             }
24             threads[nthreads] = t;//新线程t添加进数组
25
26             // This is done last so it doesn't matter in case the
27             // thread is killed
28             nthreads++;//线程数加1
29
30             // The thread is now a fully fledged member of the group, even
31             // though it may, or may not, have been started yet. It will prevent
32             // the group from being destroyed so the unstarted Threads count is
33             // decremented.
34             nUnstartedThreads--;//未启动线程数-1
35         }
36     }

启动失败后调用group.threadStartFailed(this),都是加锁方法,从线程组中移除当前线程,源码如下

 1 void threadStartFailed(Thread t) {2         synchronized(this) {3             remove(t);//移除线程t4             nUnstartedThreads++;//未启动线程+15         }6     }7 8 private void remove(Thread t) {9         synchronized (this) {
10             if (destroyed) {
11                 return;
12             }
13             for (int i = 0 ; i < nthreads ; i++) {
14                 if (threads[i] == t) {
15                     System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
16                     // Zap dangling reference to the dead thread so that
17                     // the garbage collector will collect it.
18                     threads[nthreads] = null;
19                     break;
20                 }
21             }
22         }
23     }

从Thread.start()方法看Thread源码,多次start一个线程会怎么样相关推荐

  1. 线程方法notify/notifyAll源码分析

    众所周知,使用notify/notifyAll方法能唤醒wait等待的线程,那么在底层源码究竟做了些什么呢? 本章内容要解决的问题 问题1:notify/nofityAll真的唤醒了线程吗? 问题2: ...

  2. JDK源码解析 Runable是一个典型命令模式,Runnable担当命令的角色,Thread充当的是调用者,start方法就是其执行方法

    JDK源码解析 Runnable是一个典型命令模式, Runnable担当命令的角色,Thread充当的是调用者,start方法就是其执行方法 /命令接口(抽象命令角色) public interfa ...

  3. 20种看asp源码的方法及工具

    作者:欧杨飘雪  http://blog.csdn.net/flyingsnowy/ 众所周知windows平台漏洞百出,补丁一个接一个,但总是补也补不净.我把我所知道的20种看asp源码的方法总结了 ...

  4. 最近看Kafka源码,着实被它的客户端缓冲池技术优雅到了

    最近看kafka源码,着实被它的客户端缓冲池技术优雅到了.忍不住要写篇文章赞美一下(哈哈). 注:本文用到的源码来自kafka2.2.2版本. 背景 当我们应用程序调用kafka客户端 produce ...

  5. Thread.yield()方法表示交出主动权,join表示等待当前线程,可以指定秒数

    Thread.yield()方法表示交出主动权,join表示等待当前线程,可以指定秒数 学习了:http://www.importnew.com/14958.html 膜拜一下 源码膜拜: Threa ...

  6. 一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach

    一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 代 ...

  7. 面试有没有看过spring源码_如何看Spring源码、Java每日六道面试分享,打卡第二天...

    原标题:如何看Spring源码.Java每日六道面试分享,打卡第二天 想要深入的熟悉了解Spring源码,我觉得第一步就是要有一个能跑起来的极尽简单的框架,下面我就教大家搭建一个最简单的Spring框 ...

  8. 一点一点看JDK源码(四)java.util.ArrayList 中篇

    一点一点看JDK源码(四)java.util.ArrayList 中篇 liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 在前篇中 ...

  9. 读取xml文件转成ListT对象的两种方法(附源码)

    读取xml文件转成List<T>对象的两种方法(附源码) 读取xml文件,是项目中经常要用到的,所以就总结一下,最近项目中用到的读取xml文件并且转成List<T>对象的方法, ...

最新文章

  1. jquery即时搜索查询插件jquery.search.js
  2. redis安装过程中遇到的问题
  3. 使用 xcode 8 构建版本 iTunes Connect 获取不到应用程序的状态的解决办法
  4. 打造全能的文本编辑器序列文章
  5. Seleunim 获取文本和标签属性的方法
  6. Tensorflow:Tensorboard使用
  7. PHP中插件机制的一种实现方案
  8. Python Chainmap函数 - Python零基础入门教程
  9. 使用ffmpeg一行命令根据时间分割MP4文件
  10. mongodb安装及5安装studio 3t和studio3t破解
  11. html表格(table)的基本结构
  12. 芬兰建筑师帕特里克艾瑞克森先生一行访问云创
  13. Prometheus + Grafana 搭建监控报警系统
  14. 三角(Triangle)
  15. avalonia 控件TextBox 及其他控件文本改变事件
  16. docker部署html页面,在Docker容器中部署静态网页的方法教程
  17. zipJS 前端压缩使用
  18. 论文《Context Contrasted Feature and Gated Multi-scale Aggregation for Scene Segmentation》笔记
  19. 计算机无法检索文件夹,win7系统不能搜索文件夹怎么回事
  20. 互融云农产品追溯系统:区块链存证技术实现双向可追溯

热门文章

  1. 基于angular4+ng-bootstrap+bootstrap+scss的后台管理系统界面
  2. Angular js 具体应用(一)
  3. 百度地图与HT for Web结合的GIS网络拓扑应用
  4. Tomcat -- Cannot create a server using the sel...
  5. Deverpress 中国代理商使用 官方地址
  6. 企业网站服务器负载均衡技术
  7. 【机器学习】最近邻算法KNN原理、流程框图、代码实现及优缺点
  8. 一网打尽深度学习之卷积神经网络的经典网络(LeNet-5、AlexNet、ZFNet、VGG-16、GoogLeNet、ResNet)
  9. 语音信号的分帧加窗的matlab实现
  10. 数字图像处理实验(12):PROJECT 05-03,Periodic Noise Reduction Using a Notch Filter