Java Thread初始化

构造方法

thread的构造方法分成了两类,1类是我们平时使用的公开构造方法:

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

另外还有一个构造方法,是安卓添加的用于runtime调用,内部初始化调用的方法也和上面不同。我们暂时先不看,先分析一下平时创建线程对象的这个方法。

构造方法实现直接调用了init

init

private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc) {
    //1.设置线程名
    if (name == null) {
        throw new NullPointerException("name cannot be null");
    }

    this.name = name;
    //2.设置线程的线程组,如果未指定,则此线程的线程组为当前初始化线程的线程组
    Thread parent = currentThread();
    ...
    if (g == null) {
        //这里有一段注释说,安卓不支持SecurityManager,所以删除了相关代码
        g = parent.getThreadGroup();
    }

    //所属线程组未启动线程计数+1
    g.addUnstarted();

    this.group = g;
    //3.设置线程的其他属性
    //线程是否是守护线程以及优先级都继承自当前线程
    this.daemon = parent.isDaemon();
    this.priority = parent.getPriority();
    this.target = target;
    //4.调用init2 执行剩余初始化操作
    init2(parent);
    //5.设置线程的堆栈大小。但是否生效要看虚拟机。那么在art虚拟机上是否生效呢,我们后续再说
    /* Stash the specified stack size in case the VM cares */
    this.stackSize = stackSize;

    //6.设置当前线程id
    tid = nextThreadID();
}

init2

在上面的init方法中,只是设置了一些thread的基本属性,剩余的初始化操作放在了init2中。另外,我们开头说的另一种runtime调用的构造方法,也会调用init2方法进行初始化。

private void init2(Thread parent) {
    this.contextClassLoader = parent.getContextClassLoader();//设置此线程的上下文类加载器
    this.inheritedAccessControlContext = AccessController.getContext();//这里可以看到,我们在构造方法中设置的AccessController并没有用。至于这个AccessController是什么呢,我们先不关注
    if (parent.inheritableThreadLocals != null) {
        this.inheritableThreadLocals = ThreadLocal.createInheritedMap(
                parent.inheritableThreadLocals);//设置从双亲线程继承来的ThreadLocal
    }
}

nextThreadID

private static long threadSeqNumber;
private static synchronized long nextThreadID() {
    return ++threadSeqNumber;
}

静态变量累加后返回。

到这里为止,我们的thread就已经初始化完毕了。在过程中,基本没有调用什么native方法,也没有什么特殊操作,就是简单的对thread对象的属性复制,自然也没有真的创建出一个线程。

你可能感兴趣的:(Java Thread初始化)