Java Unsafe-unpark操作

park/unpark操作

 

这两个操作通常配合在一起使用,park操作用于阻塞当前线程,unpark用于使阻塞在park操作代码处的线程退出阻塞。

 

 

unpark操作

该方法是一个native方法:

public native void unpark(Object thread);

该方法实现unsafe.cpp\hotspot\src\share\vm\prims目录下。

UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))

  UnsafeWrapper("Unsafe_Unpark");

  Parker* p = NULL;

  if (jthread != NULL) {

    oop java_thread = JNIHandles::resolve_non_null(jthread);

    if (java_thread != NULL) {

      jlong lp = java_lang_Thread::park_event(java_thread);

      if (lp != 0) {

        // This cast is OK even though the jlong might have been read

        // non-atomically on 32bit systems, since there, one word will

        // always be zero anyway and the value set is always the same

        p = (Parker*)addr_from_java(lp);

      } else {

        // Grab lock if apparently null or using older version of library

        MutexLocker mu(Threads_lock);

        java_thread = JNIHandles::resolve_non_null(jthread);

        if (java_thread != NULL) {

          JavaThread* thr = java_lang_Thread::thread(java_thread);

          if (thr != NULL) {

            p = thr->parker();

            if (p != NULL) { // Bind to Java thread for next time.

              java_lang_Thread::set_park_event(java_thread, addr_to_java(p));

            }

          }

        }

      }

    }

  }

  if (p != NULL) {

#ifndef USDT2

    HS_DTRACE_PROBE1(hotspot, thread__unpark, p);

#else /* USDT2 */

    HOTSPOT_THREAD_UNPARK(

                          (uintptr_t) p);

#endif /* USDT2 */

    p->unpark();

  }

UNSAFE_END

以上代码需要展开来才能看得懂,展开后代码如下:

如果定义了USDT2

extern "C" {

  void JNICALL Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread) {

    JavaThread* thread=JavaThread::thread_from_jni_environment(env);

    ThreadInVMfromNative __tiv(thread);

 

    /* do nothing */

 

    HandleMarkCleaner __hm(thread);

    Thread* THREAD = thread;

 

    /* begin of body */

 

    /*nothing, for the present*/;

 

    Parker* p = NULL;

    if (jthread != NULL) {

      oop java_thread = JNIHandles::resolve_non_null(jthread);

      if (java_thread != NULL) {

        jlong lp = java_lang_Thread::park_event(java_thread);

        if (lp != 0) {

          // This cast is OK even though the jlong might have been read

          // non-atomically on 32bit systems, since there, one word will

          // always be zero anyway and the value set is always the same

          p = (Parker*)addr_from_java(lp);

        } else {

          // Grab lock if apparently null or using older version of library

          MutexLocker mu(Threads_lock);

          java_thread = JNIHandles::resolve_non_null(jthread);

          if (java_thread != NULL) {

            JavaThread* thr = java_lang_Thread::thread(java_thread);

            if (thr != NULL) {

              p = thr->parker();

              if (p != NULL) { // Bind to Java thread for next time.

                java_lang_Thread::set_park_event(java_thread, addr_to_java(p));

              }

            }

          }

        }

      }

    }

    if (p != NULL) {

      ;

      p->unpark();

    }

  }

}

 

如果没有定义USDT2

这里不展开USDT2宏没有定义的那段代码

 

其中主要的代码在:

p->unpark();

 

这块代码实现在os_solaris.cpp,在\hotspot\src\os\solaris\vm目录下。

void Parker::unpark() {

  int s, status ;

  status = os::Solaris::mutex_lock (_mutex) ;

  assert (status == 0, "invariant") ;

  s = _counter;

  _counter = 1;

  status = os::Solaris::mutex_unlock (_mutex) ;

  assert (status == 0, "invariant") ;

 

  if (s < 1) {

    status = os::Solaris::cond_signal (_cond) ;

    assert (status == 0, "invariant") ;

  }

}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值