本文仅代表个人见解,如有错误,欢迎指出,期待与各位共同进步!
本文适合想要知道运行原理但又不想太深入源码的同学食用。
这是本文内容的简化图:
一、我们知道java提供了Thread类来启动线程,但是java真的可以启动线程吗?
答案是否定的,java并不能真正启动线程,而是通过调用本地方法来启动线程。private native void start0()
,start0方法是使用其他语言实现的,功能就是启动线程。
二、Thread类如何启动线程?
我们知道让一个类继承Thread类并重写run()方法,那么这个类就可以作为线程类,通过调用start方法来启动线程。
class SubThread extends Thread
new SubThread().start();
那么为什么?
我们知道子类会调用父类的无参构造,我们来看看看这个构造器。
public Thread() {
this(null, null, "Thread-" + nextThreadNum(), 0);
}
如果你去查看Thread类的源码,你就会发现在Thread所有构造器最后都通过this方法调用同一个私有构造器来完成。
// 请记住这个私有构造器
private Thread(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
...
this.name = name; // 线程的名字
...
// 这段代码,目的在于当指定线程组为空时,为当前线程创建默认线程组。
// 你可以忽略这个部分,只记住最后在线程启动时线程组不会为null即可。
SecurityManager security = System.getSecurityManager();
if (g == null) {
if (security != null) {
g = security.getThreadGroup();
}
if (g == null) {
g = parent.getThreadGroup();
}
}
...
this.group = g; // 线程将要提交的线程池
...
this.target = target; // 线程
...
}
为了便于理解,我仅保留了最为重要的部分。此时参数如下,
参数 | 值 |
---|---|
name | 默认为Thread-N |
g | null |
target | null |