探索Thread源码

3 阅读2分钟
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("(♥◠‿◠)ノ゙ლ(´ڡ`ლ)゙  ");
    }
});
thread.start();

private Thread(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();
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 manager doesn't have a strong opinion
       on the matter, use the parent thread group. */
    if (g == null) {
        g = parent.getThreadGroup();
    }
}

/* checkAccess regardless of whether or not threadgroup is
   explicitly passed in. */
g.checkAccess();

/*
 * Do we have the required permissions?
 */
if (security != null) {
    if (isCCLOverridden(getClass())) {
        security.checkPermission(
                SecurityConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
    }
}

g.addUnstarted();

this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
if (security == null || isCCLOverridden(parent.getClass()))
    this.contextClassLoader = parent.getContextClassLoader();
else
    this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext =
        acc != null ? acc : AccessController.getContext();
this.target = target;
setPriority(priority);
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
    this.inheritableThreadLocals =
        ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;

/* Set thread ID */
this.tid = nextThreadID();

}

    初始化,启动线程的过程

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

    默认情况下,如果你不指定线程的名称,那么自动给你生成的线程名称就是,Thread-0,Thread-1,以此类推的一大堆的线程

Thread parent = currentThread();

    你创建线程的时候,获取到的是currentThread(),是当前创建你的那个线程,比如说一般来说就是那个main线程,main线程在创建ServiceAliveMonitor线程,所以说此时创建线程的过程中,获取到的currentThread()就是main线程
    你创建一个线程的时候,默认他的父线程就是创建他的那个线程,比如main线程创建ServiceAliveMonitor线程,此时ServiceAliveMonitor线程的父线程就是main线程

image.png

    这段代码的意思,就是说threadGroup是不指定的,他就会自动给你处理一下,给你分配一个线程组,每个线程必须属于一个ThreadGroup的。如果你没有指定线程组,那么你默认的线程组就是父线程的线程组
    如果你的父线程是main线程的话,那么你的线程组就是main线程的线程组(main线程组)
    默认情况下,如果你没有指定你是否为daemon的话,那么你的daemon的状态是由父线程决定的,就是说如果你的父线程是daemon线程,那么你也是daemon线程;同理,你的优先级如果没有指定的话,那么就跟父线程的优先级保持一致

    每个线程其实都有一个线程id,threadId,第一个分配的线程,它的id是1,之后的线程是2,3,4,5,这样子,依次分配各个线程的id
    总结一下Thread初始化的过程蕴含的你需要知道的一些点:
    (1)创建你的线程,就是你的父线程
    (2)如果你没有指定ThreadGroup,你的ThreadGroup就是父线程的ThreadGroup
    (3)你的daemon状态默认是父线程的daemon状态
    (4)你的优先级默认是父线程的优先级
    (5)如果你没有指定线程的名称,那么默认就是Thread-0格式的名称
    (6)你的线程id是全局递增的,从1开始