1.Thread类对象只有在调用了start()方法之后,JVM虚拟机才会给我们创建一个真正的线程!否则就不能说是创建了线程!也就是说new Thread()之后,此时实际上在计算机底层,操作系统实际上并没有为我们创建线程!

在我们new Thread();的时候,我们点击源码就可以看到:

    public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}

实际上是调用了init()方法,而且这个init()方法有几个参数,这里nextThreadNum()这个方法点进去就可以看到这是个静态方法,静 态方法只会在JVM启动的时候加载一次!

那这几个参数又是什么意思呢?我们再点击去:

    private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null);
}

可以看到init方法的几个参数,第一个参数是线程组(传过来的是null),第二个参数是Runnable接口类对象,第三个参数是线程名称[从上一个init方法可以看出传递过来的名称是"Thread-数字"格式的名称],最后一个是栈的大小!然后在这个init()方法内部又调用了另一个重载的init()方法:如果此时再点就去就会看到如果线程组为null的话:

    private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
if (name == null) {
throw new NullPointerException("name cannot be null");
} this.name = name.toCharArray(); Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
/* Determine if it's an applet or not */ /* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
} /* If the security doesn't have a strong opinion of the matter
use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}

}

如果线程组为null,那么它就就会将parent的线程组赋值给这个g,那么parent又是谁呢?parent是当前线程,如上所示:p= currentThread();也就是说如果传过来的线程组为空的话,那么它会将当前线程的线程组赋值给这个g线程组对象!如下代码验证:

	public static void main(String[] args) {
//这种方式创建的线程,init方法默认传递给线程组g为null
Thread t = new Thread();
t.start();
//此时线程t的线程组实际上就是当前线程的线程组【当前线程也就是main线程,因为是main线程执行的这段代码】
System.out.println(t.getThreadGroup().getName());
System.out.println(Thread.currentThread().getName());
}

上述代码说明:如果构造线程对象时未传入ThreadGroup,Thread会默认获取父线程的ThreadGroup作为该线程的ThreadGroup,也就是说此时:父线程和子线程会在同一个ThreadGroup中!另外,如果我们此时获取到了ThreadGroup,那么我们就可以通过这个ThreadGroup的API获取到这个ThreadGroup有多少个线程在运行!按正常情况

来讲这里应该是有两个线程,那我们通过如下代码输出看一下:

	public static void main(String[] args) {
//这种方式创建的线程,init方法默认传递给线程组g为null
Thread t = new Thread(){
@Override
public void run() {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t.start();
ThreadGroup group = t.getThreadGroup();
int count = group.activeCount();
//创建一个线程列表
Thread[] threads= new Thread[count];
//我们可以通过线程组的enumerate()方法将线程都放到这个线程列表中,便于我们查看!
group.enumerate(threads);
//System.out.println(group.activeCount());
for(Thread temp :threads){
System.out.println(temp);
}
}

输出结果如下所示:

Thread[main,5,main]
Thread[Thread-0,5,main]

注意:如果构造线程对象时没有传入ThreadGroup,Thread会默认获取父线程的ThreadGroup作为该线程的ThreadGroup,

     此时子线程和父线程将会在同一个ThreadGroup中

那我们能不能在创建线程对象的时候,直接传入ThreadGroup类型的对象呢?当 然是可以的,以下四种构造函数:

构造函数一:

    public Thread(ThreadGroup group, Runnable target) {
init(group, target, "Thread-" + nextThreadNum(), 0);
}

构造函数二:

    public Thread(ThreadGroup group, String name) {
init(group, null, name, 0);
}

构造函数三:

    public Thread(ThreadGroup group, Runnable target, String name) {
init(group, target, name, 0);
}

构造函数四:  

    public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
init(group, target, name, stackSize);
}

至于ThreadGroup的知识点,我们这里先不展开讲,后面我们会给大家详细的讲解ThreadGroup这些知识!需要注意的是这里有个参数是stackSize,这个参数指的是栈大小,实际上也就是指虚拟机栈的大小!虚拟机栈是线程所私有的,也就是说每一个方法执行的时候都会创建一个栈帧放在虚拟机栈中!当JVM创建主线程(main线程)的时候就在内存中开辟了一块空间:虚拟机栈。

需要注意的是:在内存中,堆的大小是比较大的【存对象和数组】,而栈的地址不怎么大,这里仅仅是存地址引用,所以比较小! 

总结1:构造函数new Thread();  创建线程对象Thread,默认有一个线程名,都是以Thread-开头,从0开始!形如:

     Thread-0 Thread-1 Thread-2 Thread-3等! 而且这种构造方法的target会被传递为null!也就是用这个构造

     方法时最终Runnable类型的target对象会被设置为null!此时再看源码就可以知道如果target被设置为null,那

       么start()方法在调用start0()方法,而start0()方法在调用run()方法的时候就不会再调用Runnable实现类的run()

    方法,那么此时如果不调用target对象的run方法,我们此时就要自己重写这个Thread类 的run方法了,此时

       调用Thread类对象的start方法,才会执行我们自己写的run方法,如果我们自己此时也不重写Thread类的run

       方法,那么什么也不会执行!

总结2:当然我们也可以使用Thread(String name)这个构造函数给线程对象起一个名子!

总结3:我们可以通过Thread(Runnable target, String name)这个构造函数在创建Thread对象的时候给Thread传递一个

        Runnable接口实现类对象和线程名!

4.构造Thread对象你也许不知道的几件事的更多相关文章

  1. java线程基础巩固---构造Thread对象你也许不知道的几件事

    关于Thread的构造在JDK文档中如下: 之后会把上面所有的构造都会学习到,这次主要是去研究一下图上标红的默认构造,当然大家肯定对于它都有些不屑,这有啥可学的,不new一个然后start线程不就启动 ...

  2. (转)关于 Java 对象序列化您不知道的 5 件事

    关于 Java 对象序列化您不知道的 5 件事 转自:http://developer.51cto.com/art/201506/479979.htm 数年前,当和一个软件团队一起用 Java 语言编 ...

  3. 关于 Java 对象序列化您不知道的 5 件事

    数年前,当和一个软件团队一起用 Java 语言编写一个应用程序时,我体会到比一般程序员多知道一点关于 Java 对象序列化的知识所带来的好处. 关于本系列 您觉得自己懂 Java 编程?事实上,大多数 ...

  4. 【译】Surface中你也许不知道的五件事

    Bring up the Quick Link Menu - Select the Windows Key + X or right click the Start Button to bring u ...

  5. 关于Promise:你可能不知道的6件事

    FROM ME : 文章介绍了6个Promise的知识点: 1.then() 返回一个 forked Promise(分叉的 Promise):返回的有两种情况: 2.回调函数应该传递结果:在 pro ...

  6. 关于 Java Collections API 您不知道的 5 件事--转

    第 1 部分 http://www.ibm.com/developerworks/cn/java/j-5things2.html 对于很多 Java 开发人员来说,Java Collections A ...

  7. 关于 Java Collections API 您不知道的 5 件事,第 1 部分

    定制和扩展 Java Collections Java™ Collections API 远不止是数组的替代品,虽然一开始这样用也不错.Ted Neward 提供了关于用 Collections 做更 ...

  8. 关于 java.util.concurrent 您不知道的 5 件事--转

    第 1 部分 http://www.ibm.com/developerworks/cn/java/j-5things4.html Concurrent Collections 是 Java™ 5 的巨 ...

  9. JavaScript中你可能不知道的九件事

    今天凑巧去W3School扫了一遍JavaScript教程,发现从中看到了不少自己曾经没有注意过的细节. 我这些细节列在这里.分享给可能相同不知道的朋友: 1.使用 document.write() ...

随机推荐

  1. IDEA指定启动JDK版本

    使用场景: 开发人员在自己的机器上可能装了多个版本的JDK,但是在环境变量中只能配置一个 JAVA_HOME ,so你的IDEA Eclipse 可能因为你在 JAVA_HOME 配置JDK1.8 以 ...

  2. MovieLens电影数据分析

    下载数据包 链接:https://grouplens.org/datasets/movielens/1m/ 解压: 四个文件分别是数据介绍,电影数据表,电影评分表,用户表 进行电影数据分析 进入ipy ...

  3. Javabean非空变量校验工具

    摘要 调研java Class getDeclaredFields() 与getFields()的区别,设计请求参数为Javabean时,基于反射机制校验其中非空变量的公共方法. java Class ...

  4. es中如何定位不合法搜索

    GET /test_index/test_type/_validate/query?explain{ "query": { "math": { "te ...

  5. Redis 安装、配置、集群

    1.   Redis的安装 1.1. Redis的安装 Redis是c语言开发的. 安装redis需要c语言的编译环境.如果没有gcc需要在线安装.yum install gcc-c++ 安装步骤: ...

  6. java之httpClient 3.x、AsyncHttpClient1.9.x使用总结

    首先请大牛们见谅菜鸟重复造轮子的学习方式,本文适合新手看~ 下面使用的同步http是HttpClient 3.X的版本,不过早已不在维护,如果刚开始使用http,建议大家都换成4.X版本,别看下面的有 ...

  7. 萌新接触前端的第二课——CSS

    前端知识——CSS CSS(英文全称:Cascading Style Sheets) 中文名层叠样式表,是一种用来表现HTML或XML等文件样式的计算机语言.CSS不仅可以静态地修饰网页,还可以配合各 ...

  8. 【SVD、特征值分解、PCA关系】

    一.SVD    1.含义: 把矩阵分解为缩放矩阵+旋转矩阵+特征向量矩阵. A矩阵的作用是将一个向量从V这组正交基向量的空间旋转到U这组正交基向量的空间,并对每个方向进行了一定的缩放,缩放因子就是各 ...

  9. PHP数字字符串左侧补0、字符串填充和自动补齐的几种方法

    一.数字补0. 如果要自动生成学号,自动生成某某编号,就像这样的形式“d0000009”.“d0000027”时,那么就会面临一个问题,怎么把左边用0补齐成这样8位数的编码呢?我想到了两种方法实现这个 ...

  10. 进程理论 阻塞非阻塞 同步异步 I/O操作

    1.什么是进程 进程指的是一个正在运行的程序,进程是用来描述程序执行过程的虚拟概念 进程的概念起源于操作系统,进程是操作系统最核心的概念,操作系统其它所有的概念都是围绕进程来的 2.操作系统 操作系统 ...