src/hotspot/share/runtime/threadSMR.hpp has an example of the correct usage of ThreadsListHandle to protect JavaThread:
// ThreadsListHandle tlh;
// JavaThread* jt = nullptr;
// bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &jt, nullptr);
// if (is_alive) {
// : // do stuff with 'jt'...
// }
java_lang_Thread::async_get_stack_trace() does not follow the pattern, but does:
JNIHandles::resolve(jthread) (in JVM_GetStackTrace)
ThreadsListHandle tlh(JavaThread::current());
JavaThread* thread = java_lang_Thread::thread(java_thread);
// ThreadsListHandle tlh;
// JavaThread* jt = nullptr;
// bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &jt, nullptr);
// if (is_alive) {
// : // do stuff with 'jt'...
// }
java_lang_Thread::async_get_stack_trace() does not follow the pattern, but does:
JNIHandles::resolve(jthread) (in JVM_GetStackTrace)
ThreadsListHandle tlh(JavaThread::current());
JavaThread* thread = java_lang_Thread::thread(java_thread);