这可以通过JVMTI代理来实现。
这个想法是拦截本机Thread.start0()
方法并在调用它时抛出异常。
这是一个用 C++ 编写的示例代理:
#include <jvmti.h>
// Original native implementation of Thread.start0(), if you wish to call it
extern "C" void JNICALL JVM_StartThread(JNIEnv* env, jthread thread);
void JNICALL StartThreadHook(JNIEnv* env, jthread thread) {
env->ThrowNew(env->FindClass("java/lang/Error"), "Threads forbidden");
}
void JNICALL VMInit(jvmtiEnv* jvmti, JNIEnv* env, jthread thread) {
// After VM is initialized, intercept Thread.start0() with our hook function
jclass thread_class = env->FindClass("java/lang/Thread");
JNINativeMethod start0 = {(char*)"start0", (char*)"()V", (void*)StartThreadHook};
env->RegisterNatives(thread_class, &start0, 1);
}
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
jvmtiEnv* jvmti;
vm->GetEnv((void**)&jvmti, JVMTI_VERSION_1_0);
jvmtiEventCallbacks callbacks = {0};
callbacks.VMInit = VMInit;
jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
return 0;
}
编译代理:
g++ -fPIC -shared -olibnothreads.so -Wl,-soname,libnothreads.so nothreads.cpp
使用代理运行应用程序:
java -agentpath:/path/to/libnothreads.so -jar app.jar
请注意,您还可以使用 JVMTI 来实现自定义逻辑,何时允许以及何时拒绝启动新线程。例如,ThreadStart和ThreadEnd事件将有助于计算创建的线程。GetStackTrace函数将帮助找出哪些类正在尝试创建线程。