【问题标题】:What is the difference between JVMTI SuspendThread and Javas thread.suspend?JVMTI SuspendThread 和 Java 的 thread.suspend 有什么区别?
【发布时间】:2019-02-09 20:35:27
【问题描述】:

在 JVMTI 代理中使用 SuspendThread 和使用普通 Java thread.suspend() 有什么区别?

【问题讨论】:

    标签: java multithreading thread-safety jvmti


    【解决方案1】:

    在 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");
    
      ...
    

    【讨论】:

      猜你喜欢
      • 2011-06-02
      • 2010-09-19
      • 1970-01-01
      • 2011-07-30
      • 1970-01-01
      • 2020-02-06
      • 2022-12-04
      相关资源
      最近更新 更多