第二章:深入理解Thread构造函数

线程的命名

线程的默认命名:

  • Thread()
  • Thread(Runnable target)
  • Thread(ThreadGroup group,Runnable target)

如果没有为线程显示地指定一个名字,那么线程会以“Thread-”作为前缀与一个自增数字进行组合,这个自增数字在整个JVM进程中会不断自增。

关于修改线程名:

public final synchronized void setName(String name) {
        checkAccess();
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;
        if (threadStatus != 0) {
            setNativeName(name);
        }
    }

线程不是NEW状态,对其的修改将不会生效。

线程的父子关系
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;

        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();

一个线程的创建肯定是由另一个线程完成。

被创建线程的父线程一定是创建它的线程。

Thread与ThreadGroup
 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();
            }
        }

如果在构造Thread的时候没有显式地指定一个ThreadGroup,那么子线程将会被加入到父线程所在的线程组,并且和父线程同一个优先级。

main线程所在的ThreadGroup称为main。

Thread与JVM虚拟机栈

stacksize越大代表着正在线程内方法调用递归的深度就越深,statcksize越小则代表着创建的线程数量越多。

JVM内存结构

1.程序计数器:

程序计数器在JVM中所起的作用就是存放当前线程接下来将要执行的字节码指令、分支、循环、跳转、异常处理等。在任何时候,一个处理器值执行其中的一个线程指令,为了能够在CPU时间片轮转切换上下文之后顺利回到正确的执行位置,每条线程都需要独立的计数器,个线程之间互不影响,因此JVM将此块内存区域设计成了线程私有的。

2.JAVA虚拟机栈:

java虚拟机栈也是线程私有的,它的生命周期与线程相同,是在JVM运行时创建的。在线程中,方法在执行的时候都会创建一个名为栈帧的数据结构。一般将栈帧内存的大小称为宽度,栈帧的数量则称为虚拟机栈的深度。

3.本地方法栈:

JVM为本地方法所划分的内存区域,而且它是线程私有的。

4.堆内存:

堆内存是JVM中最大的一块内存区域,被所有线程共享。

5.方法区:

方法区也是被多个线程所共享的内存区域,它主要用于储存已被虚拟机加载的类信息、常量、静态变量、即时编译器(JIT)编译后的代码等数据。(堆内存的一个逻辑区域)

Thread与虚拟机栈

栈内存划分的大小将直接决定在一个JVM进程中可以创建多少个线程。

java进程的粗略大小=堆内存+线程数量*栈内存

线程数量=(最大地址空间 - JVM堆内存 - ReservedOsMemory)/ThreadStackSize

守护线程

守护线程具备自动结束生命周期的特性。

若JVM中没有一个非守护线程,则JVM的进程会退出。
守护线程一般用于处理一些后台操作。

父线程是守护线程,子线程也会是守护线程。反之亦然。

设置守护线程:

在启动前调用setDaemon()方法才能生效。如果一个线程已经死亡,那么再设置会抛出IllegalThreadStateException。

使用守护线程:

希望当关闭某些线程的时候(可以是JVM),同时自动关闭一些线程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值