JVMTI SuspendThread 和 Javas thread.suspend 有什么区别?
What is the difference between JVMTI SuspendThread and Javas thread.suspend?
使用SuspendThread from a JVMTI agent and using the plain Java thread.suspend()有什么不同吗?
在 HotSpot JVM 中,两个 API 具有相同的效果。
我已经添加了指向 OpenJDK 源代码相关部分的链接。这两个函数几乎是彼此的复制粘贴,它们最终都调用了相同的低级例程 JavaThread::java_suspend()
.
native code java.lang.Thread.suspend0()
:
JVM_ENTRY(void, JVM_SuspendThread(JNIEnv* env, jobject jthread))
JVMWrapper("JVM_SuspendThread");
ThreadsListHandle tlh(thread);
JavaThread* receiver = NULL;
bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
if (is_alive) {
// jthread refers to a live JavaThread.
{
MutexLockerEx ml(receiver->SR_lock(), Mutex::_no_safepoint_check_flag);
if (receiver->is_external_suspend()) {
// Don't allow nested external suspend requests. We can't return
// an error from this interface so just ignore the problem.
return;
}
if (receiver->is_exiting()) { // thread is in the process of exiting
return;
}
receiver->set_external_suspend();
}
// java_suspend() will catch threads in the process of exiting
// and will ignore them.
receiver->java_suspend();
// It would be nice to have the following assertion in all the
// time, but it is possible for a racing resume request to have
// resumed this thread right after we suspended it. Temporarily
// enable this assertion if you are chasing a different kind of
// bug.
//
// assert(java_lang_Thread::thread(receiver->threadObj()) == NULL ||
// receiver->is_being_ext_suspended(), "thread is not suspended");
}
JVM_END
JVM TI SuspendThread的implementation:
jvmtiError
JvmtiEnv::SuspendThread(JavaThread* java_thread) {
// don't allow hidden thread suspend request.
if (java_thread->is_hidden_from_external_view()) {
return (JVMTI_ERROR_NONE);
}
{
MutexLockerEx ml(java_thread->SR_lock(), Mutex::_no_safepoint_check_flag);
if (java_thread->is_external_suspend()) {
// don't allow nested external suspend requests.
return (JVMTI_ERROR_THREAD_SUSPENDED);
}
if (java_thread->is_exiting()) { // thread is in the process of exiting
return (JVMTI_ERROR_THREAD_NOT_ALIVE);
}
java_thread->set_external_suspend();
}
if (!JvmtiSuspendControl::suspend(java_thread)) {
// the thread was in the process of exiting
return (JVMTI_ERROR_THREAD_NOT_ALIVE);
}
return JVMTI_ERROR_NONE;
} /* end SuspendThread */
bool JvmtiSuspendControl::suspend(JavaThread *java_thread) {
// external suspend should have caught suspending a thread twice
// Immediate suspension required for JPDA back-end so JVMTI agent threads do
// not deadlock due to later suspension on transitions while holding
// raw monitors. Passing true causes the immediate suspension.
// java_suspend() will catch threads in the process of exiting
// and will ignore them.
java_thread->java_suspend();
// It would be nice to have the following assertion in all the time,
// but it is possible for a racing resume request to have resumed
// this thread right after we suspended it. Temporarily enable this
// assertion if you are chasing a different kind of bug.
//
// assert(java_lang_Thread::thread(java_thread->threadObj()) == NULL ||
// java_thread->is_being_ext_suspended(), "thread is not suspended");
...
使用SuspendThread from a JVMTI agent and using the plain Java thread.suspend()有什么不同吗?
在 HotSpot JVM 中,两个 API 具有相同的效果。
我已经添加了指向 OpenJDK 源代码相关部分的链接。这两个函数几乎是彼此的复制粘贴,它们最终都调用了相同的低级例程 JavaThread::java_suspend()
.
native code java.lang.Thread.suspend0()
:
JVM_ENTRY(void, JVM_SuspendThread(JNIEnv* env, jobject jthread))
JVMWrapper("JVM_SuspendThread");
ThreadsListHandle tlh(thread);
JavaThread* receiver = NULL;
bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
if (is_alive) {
// jthread refers to a live JavaThread.
{
MutexLockerEx ml(receiver->SR_lock(), Mutex::_no_safepoint_check_flag);
if (receiver->is_external_suspend()) {
// Don't allow nested external suspend requests. We can't return
// an error from this interface so just ignore the problem.
return;
}
if (receiver->is_exiting()) { // thread is in the process of exiting
return;
}
receiver->set_external_suspend();
}
// java_suspend() will catch threads in the process of exiting
// and will ignore them.
receiver->java_suspend();
// It would be nice to have the following assertion in all the
// time, but it is possible for a racing resume request to have
// resumed this thread right after we suspended it. Temporarily
// enable this assertion if you are chasing a different kind of
// bug.
//
// assert(java_lang_Thread::thread(receiver->threadObj()) == NULL ||
// receiver->is_being_ext_suspended(), "thread is not suspended");
}
JVM_END
JVM TI SuspendThread的implementation:
jvmtiError
JvmtiEnv::SuspendThread(JavaThread* java_thread) {
// don't allow hidden thread suspend request.
if (java_thread->is_hidden_from_external_view()) {
return (JVMTI_ERROR_NONE);
}
{
MutexLockerEx ml(java_thread->SR_lock(), Mutex::_no_safepoint_check_flag);
if (java_thread->is_external_suspend()) {
// don't allow nested external suspend requests.
return (JVMTI_ERROR_THREAD_SUSPENDED);
}
if (java_thread->is_exiting()) { // thread is in the process of exiting
return (JVMTI_ERROR_THREAD_NOT_ALIVE);
}
java_thread->set_external_suspend();
}
if (!JvmtiSuspendControl::suspend(java_thread)) {
// the thread was in the process of exiting
return (JVMTI_ERROR_THREAD_NOT_ALIVE);
}
return JVMTI_ERROR_NONE;
} /* end SuspendThread */
bool JvmtiSuspendControl::suspend(JavaThread *java_thread) {
// external suspend should have caught suspending a thread twice
// Immediate suspension required for JPDA back-end so JVMTI agent threads do
// not deadlock due to later suspension on transitions while holding
// raw monitors. Passing true causes the immediate suspension.
// java_suspend() will catch threads in the process of exiting
// and will ignore them.
java_thread->java_suspend();
// It would be nice to have the following assertion in all the time,
// but it is possible for a racing resume request to have resumed
// this thread right after we suspended it. Temporarily enable this
// assertion if you are chasing a different kind of bug.
//
// assert(java_lang_Thread::thread(java_thread->threadObj()) == NULL ||
// java_thread->is_being_ext_suspended(), "thread is not suspended");
...