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

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

 /**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
* <p>线程被执行,JVM调用run方法
* 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.多次调用start方法启动一个线程是非法的
* In particular, a thread may not be restarted once it has completed
* execution.
*
* @exception IllegalThreadStateException if the thread was already已经启动的线程再次start,异常
* 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)//状态校验 0:NEW 新建状态
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();//调用native方法执行线程run方法
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 */
}
}
} private native void start0();

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

 /**
* Adds the specified thread to this thread group.
*
* <p> Note: This method is called from both library code
* and the Virtual Machine. It is called from VM to add
* certain system threads to the system thread group.
*
* @param t
* the Thread to be added
*
* @throws IllegalThreadStateException
* if the Thread group has been destroyed
*/
void add(Thread t) {
synchronized (this) {
if (destroyed) {//线程组状态校验
throw new IllegalThreadStateException();
}
if (threads == null) {
threads = new Thread[4];//初始化长度为4的Thread数组
} else if (nthreads == threads.length) {//数组满了就扩容2倍
threads = Arrays.copyOf(threads, nthreads * 2);
}
threads[nthreads] = t;//新线程t添加进数组 // This is done last so it doesn't matter in case the
// thread is killed
nthreads++;//线程数加1 // The thread is now a fully fledged member of the group, even
// though it may, or may not, have been started yet. It will prevent
// the group from being destroyed so the unstarted Threads count is
// decremented.
nUnstartedThreads--;//未启动线程数-1
}
}

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

 void threadStartFailed(Thread t) {
synchronized(this) {
remove(t);//移除线程t
nUnstartedThreads++;//未启动线程+1
}
} private void remove(Thread t) {
synchronized (this) {
if (destroyed) {
return;
}
for (int i = 0 ; i < nthreads ; i++) {
if (threads[i] == t) {
System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
// Zap dangling reference to the dead thread so that
// the garbage collector will collect it.
threads[nthreads] = null;
break;
}
}
}
}

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

  1. 一点一点看JDK源码(五)java.util.ArrayList 后篇之Spliterator多线程遍历

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

  2. java 集合与数组的互转方法,与源码分析

    前言 java数组与集合需要互相转换的场景非常多,但是运用不好还是容易抛出UnSupportedOperationException.下面讲解一下互转的方法,以及结合源码分异常产生的原因 集合转数组 ...

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

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

  4. Java线程状态、线程start方法源码、多线程、Java线程池、如何停止一个线程

    下面将依次介绍: 1. 线程状态.Java线程状态和线程池状态 2. start方法源码 3. 什么是线程池? 4. 线程池的工作原理和使用线程池的好处 5. ThreadPoolExecutor中的 ...

  5. 【实习记】2014-08-15文档太少看着源码用cgicc+stl库之模板谓词函数对象

        总结1: 今天找到了昨天scanf的问题答案,scanf与printf一样的神奇而复杂,稍不留神,就会被坑.scanf函数在读入非空白符分割的多个字符串的解决方法是这个:/* 以 | 分割 * ...

  6. 读取xml文件转成List<T>对象的两种方法(附源码)

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

  7. 一点一点看JDK源码(〇)

    一点一点看JDK源码(〇) liuyuhang原创,未经允许进制转载 写在前面: 几乎所有的大神都会强调看源码,也强调源码的重要性: 但是如何看源码,源码看什么?看了什么用?看了怎么用? 困扰很多人, ...

  8. 一点一点看JDK源码(一)Collection体系概览

    一点一点看JDK源码(一)Collection体系概览 liuyuhang原创,未经允许进制转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 Collection为集 ...

  9. 一点一点看JDK源码(二)java.util.List

    一点一点看JDK源码(二)java.util.List liuyuhang原创,未经允许进制转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 List译为表,一览表, ...

随机推荐

  1. Servlet知识点

    如果请求采用Get方式,则重写doGet()方法,如果请求采用Post方式,则重写doPost()方法. 下面是重写doGet()方法的servlet例子. servlet继承如下类: 整体结构: 在 ...

  2. MySQL使用聚合函数查询

    create table `t_grade` ( `id` int , `stuName` varchar (60), `course` varchar (60), `score` int ); in ...

  3. 数据结构之R进制转换

    废话不多说,直接上代码 #include <stdio.h> int exchange(int a) { char c='A'; if(a>=10) { printf("% ...

  4. Java基础---其他对象

    第一讲     System类 一.概述 1.System是描述系统一些信息的类,类中的属性和方法都是静态的.不能被实例化,没有提供构造函数. 2.字段摘要 out:标准输出流.默认是控制台. in: ...

  5. Android项目实战(三十四):蓝牙4.0 BLE 多设备连接

    最近项目有个需求,手机设备连接多个蓝牙4.0 设备 并获取这些设备的数据. 查询了很多资料终于实现,现进行总结. ------------------------------------------- ...

  6. sql优化策略之索引失效情况二

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp63   接第一篇索引失效分析:http://grefr.iteye.co ...

  7. 实现Spring RESTful服务的SSL

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt386 本文介绍如何让基于Spring的REST服务变得SSL/TSL化. 首 ...

  8. VS2012启用angularjs智能提示Intelligence(转)

    1. 關閉正在執行的 Visual Studio 2012 2. 開啟檔案總管,並進入以下目錄: C:\Program Files (x86)\Microsoft Visual Studio 11.0 ...

  9. jvm系列 (五) ---类加载机制

    类的加载机制 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 jvm系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...

  10. 201521123085 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1. 代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过 ...