首先,你可以通过创建多个Thread
个对象来try 这一点,然后try 启动所有这些Thread
对象:
public class ThreadRunner {
public static void main(String[] args) {
int maxThreads = 10_000_000;
// Create Thread instances
Thread[] threads = new Thread[maxThreads];
Runnable r = () -> {
try {
Thread.sleep(1000_000);
} catch (InterruptedException e) {
}
};
for (int i = 0; i < maxThreads; i++) {
threads[i] = new Thread(r);
}
// start Threads
int count = 0;
try {
for (Thread t : threads) {
t.start();
count++;
if (count % 1000 == 0) {
System.out.println(count);
}
Thread.yield();
}
} catch (OutOfMemoryError e) {
System.out.println(count);
}
}
}
另一种方法是判断OpenJDK的源代码:
{"start0", "()V", (void *)&JVM_StartThread},
jvm.cpp包含本机函数,该函数确定本机线程的堆栈大小,然后使用
jlong size =
java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));
// Allocate the C++ Thread structure and create the native thread. The
// stack size retrieved from java is 64-bit signed, but the constructor takes
// size_t (an unsigned type), which may be 32 or 64-bit depending on the platform.
// - Avoid truncating on 32-bit platforms if size is greater than UINT_MAX.
// - Avoid passing negative values which would result in really large stacks.
NOT_LP64(if (size > SIZE_MAX) size = SIZE_MAX;)
size_t sz = size > 0 ? (size_t) size : 0;
native_thread = new JavaThread(&thread_entry, sz);
这取决于具体的JVM实现吗?
原则上,这可能取决于特定的JVM实现.然而,在真正需要之前创建操作系统线程将是愚蠢的.
我说这很愚蠢的主要原因是资源管理.当您创建操作系统线程时,您还必须销毁它.当你start()
a Thread
操作系统线程被创建时,线程run()
方法被执行,并且在该方法返回之后,操作系统线程将被销毁.
如果假设的JVM实现创建了Thread
构造函数中已经存在的OS线程,那么当Thread
实例被垃圾收集时,它还需要某种方法来销毁该OS线程,这将是很麻烦的.