我们知道在Java中创建线程整体上需要三步:
1.为线程堆栈分配并初始化一块内存区域
2.进行系统调用在OC中创建/注册一个本机线程
3.初始化线程文件描述符,并将其添加到JVM内部的数据结构中。
当考虑Java创建线程成本高的问题问题时首先要知道当new thread()时做了什么?
首先,我们知道Java中万物皆为对象,因此我们知道,new Object()过程必然包含在创建线程中。
然后,当执行new thread()时,除了执行了new Object()标准化过程外还执行了什么动作,我们知道Java中的线程与操作系统中的线程时一一对应的,因此创建一个线程还要调用操作系统内核API去创建新的线程。
JVM创建新线程时需要经历如下几步:
1.为线程栈分配内存,栈为该线程每个方法保存一个栈帧。
2.每个栈由一个常量数组、返回值、操作数堆栈和常量池组成
3.一些支持本机方法的JVM也会分配一个本机堆栈
4.每个线程获得一个程序计数器,告诉线程当前处理器的执行指令是什么
5.系统创建一个与Java线程对应的本机线程
6.将与线程相关的文件描述符增加到JVM内部数据结构中
7.线程共享堆和方法区。
我们使用Java 8来验证一下创建一个什么都不做的线程需要消耗多少空间和时间
java -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics -version
我们使用命令可以看到,16个线程,栈中reserved和committed共占16M左右,因此每个线程大约占1M
消耗时间,我们创建16个线程每个线程只获取当前状态需要的时间计时,共需要(end - start)ms
public class TestCreateThread {
public static void main(String[] args) {
long startTime=System.nanoTime();
for(int i = 0; i < 16; i++) {
Thread thread = new Thread(() -> {});
System.out.println(thread.getState());
}
long endTime=System.nanoTime();
System.out.println("strat " + startTime);
System.out.println("end " + endTime);
}
}
strat 64396783831819
end 64396827362578
由结果可得出,16个线程创建需要 43,530,759ns = 43.5308ms
作者:tulip
链接:https://juejin.cn/post/6893110021878611981
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。