成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

OpenJDK9 Hotspot : Object wait/notify 方法淺析

fancyLuo / 2890人閱讀

摘要:前言方法是早期提供的一種基于的線程同步方法,本文先介紹相關(guān)的數(shù)據(jù)結(jié)構(gòu)類,然后從方法的內(nèi)部實(shí)現(xiàn)入手,簡(jiǎn)單分析相關(guān)的原理和實(shí)現(xiàn)類用于實(shí)現(xiàn)的定待和喚醒,不同平臺(tái)操作系統(tǒng)平臺(tái)對(duì)應(yīng)的定義在文件類的分配和釋放使用了對(duì)象緩存,靜態(tài)字段用于緩存當(dāng)前

前言

Object wait/notify 方法是早期 JVM 提供的一種基于 Object Monitor 的線程同步方法,本文先介紹相關(guān)的數(shù)據(jù)結(jié)構(gòu)(類),然后從 wait/notify 方法的內(nèi)部實(shí)現(xiàn)入手,簡(jiǎn)單分析 Object Monitor 相關(guān)的原理和實(shí)現(xiàn)

Park

Per-thread blocking support for JSR166. Basically, park acts like wait, uppark like notify

Park 類用于實(shí)現(xiàn) JavaThread 的定待(park/wait)和喚醒(unpark/notify),不同平臺(tái)(操作系統(tǒng))

PlatformParker

linux 平臺(tái)對(duì)應(yīng)的 PlatformParker 定義在 hotspot/src/os/linux/vm/os_linux.hpp 文件

class PlatformParker : public CHeapObj {
 protected:
  enum {
    REL_INDEX = 0,
    ABS_INDEX = 1
  };
  int _cur_index;  // which cond is in use: -1, 0, 1
  pthread_mutex_t _mutex[1];
  pthread_cond_t  _cond[2]; // one for relative times and one for abs.

 public:       // TODO-FIXME: make dtor private
  ~PlatformParker() { guarantee(0, "invariant"); }

 public:
  PlatformParker() {
    int status;
    status = pthread_cond_init(&_cond[REL_INDEX], os::Linux::condAttr());
    assert_status(status == 0, status, "cond_init rel");
    status = pthread_cond_init(&_cond[ABS_INDEX], NULL);
    assert_status(status == 0, status, "cond_init abs");
    status = pthread_mutex_init(_mutex, NULL);
    assert_status(status == 0, status, "mutex_init");
    _cur_index = -1; // mark as unused
  }
};
allocate & release

Parker 類的分配和釋放使用了對(duì)象緩存,靜態(tài)字段 FreeList 用于緩存當(dāng)前所有可用的 Parker,ListLock 用于實(shí)現(xiàn)對(duì) FreeList 鎖,靜態(tài)方法 Allocate 和 Release 用于分配和釋放 Parker

class Parker {
    ...
public:
    ...
    static Parker *Allocate(JavaThread *t);
    static void Release(Parker *e);
private:
    static Parker *volatile FreeList;
    static volatile int ListLock;
}

Allocate 方法首先嘗試從 FreeList 中獲取 Parker,在此之前要先獲取 ListLock;如果分配失敗則嘗試 new 一個(gè)新的 parker,最后設(shè)置 Parker 的 AssociatedWith 字段將 Parker 和 JavaThread 關(guān)聯(lián)

Parker * Parker::Allocate (JavaThread * t) {
  guarantee (t != NULL, "invariant") ;
  Parker * p ;

  // Start by trying to recycle an existing but unassociated
  // Parker from the global free list.
  // 8028280: using concurrent free list without memory management can leak
  // pretty badly it turns out.
  Thread::SpinAcquire(&ListLock, "ParkerFreeListAllocate");
  {
    p = FreeList;
    if (p != NULL) {
      FreeList = p->FreeNext;
    }
  }
  Thread::SpinRelease(&ListLock);

  if (p != NULL) {
    guarantee (p->AssociatedWith == NULL, "invariant") ;
  } else {
    // Do this the hard way -- materialize a new Parker..
    p = new Parker() ;
  }
  p->AssociatedWith = t ;          // Associate p with t
  p->FreeNext       = NULL ;
  return p ;
}
park unpark ObjectMonitor ObjectSynchronizer wait

Object 類中的很多方法都是 native 方法,wait 也不例外

public final void wait() throws InterruptedException {
    wait(0);
}

public final native void wait(long timeout) throws InterruptedException;

wait 方法對(duì)應(yīng)的 native 函數(shù)為 JVM_MonitorWait

JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms))
  JVMWrapper("JVM_MonitorWait");
  Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
  JavaThreadInObjectWaitState jtiows(thread, ms != 0);
  if (JvmtiExport::should_post_monitor_wait()) {
    JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms);

    // The current thread already owns the monitor and it has not yet
    // been added to the wait queue so the current thread cannot be
    // made the successor. This means that the JVMTI_EVENT_MONITOR_WAIT
    // event handler cannot accidentally consume an unpark() meant for
    // the ParkEvent associated with this ObjectMonitor.
  }
  ObjectSynchronizer::wait(obj, ms, CHECK);
JVM_END

它首先調(diào)用 JNIHandles::resolve_non_null 函數(shù)將 jobject 類型的 handle 轉(zhuǎn)化為 oop(關(guān)于 oop 和 Handle 概念可以參考之前的系列文章),然后調(diào)用 ObjectSynchronizer 類的靜態(tài)方法 wait,這里出現(xiàn)了第一個(gè)和 Object Monitor 相關(guān)的類 ObjectSynchronizer,先做個(gè)標(biāo)記,接著往下看

int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) {
  if (UseBiasedLocking) {
    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
    assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
  }
  if (millis < 0) {
    TEVENT(wait - throw IAX);
    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
        "timeout value is negative");
  }
  ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD,
                                                       obj(),
                                                       inflate_cause_wait);

  DTRACE_MONITOR_WAIT_PROBE(monitor, obj(), THREAD, millis);
  monitor->wait(millis, true, THREAD);

  // This dummy call is in place to get around dtrace bug 6254741.  Once
  // that"s fixed we can uncomment the following line, remove the call
  // and change this function back into a "void" func.
  // DTRACE_MONITOR_PROBE(waited, monitor, obj(), THREAD);
  return dtrace_waited_probe(monitor, obj, THREAD);
}

這里出現(xiàn)了第二個(gè)類 ObjectMonitor(主角),通過(guò) ObjectSynchronizer::inflate 方法獲取對(duì)象的 ObjectMonitor 后調(diào)用 monitor 的 wait 方法.

總結(jié)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66728.html

相關(guān)文章

  • 線程間的同步與通信(3)——淺析synchronized的實(shí)現(xiàn)原理

    摘要:由此可見(jiàn),自旋鎖和各有優(yōu)劣,他們分別適用于競(jìng)爭(zhēng)不多和競(jìng)爭(zhēng)激烈的場(chǎng)景中。每一個(gè)試圖進(jìn)入同步代碼塊的線程都會(huì)被封裝成對(duì)象,它們或在對(duì)象的中,或在中,等待成為對(duì)象的成為的對(duì)象即獲取了監(jiān)視器鎖。 前言 系列文章目錄 前面兩篇文章我們介紹了synchronized同步代碼塊以及wait和notify機(jī)制,大致知道了這些關(guān)鍵字和方法是干什么的,以及怎么用。 但是,知其然,并不知其所以然。 例如...

    keithxiaoy 評(píng)論0 收藏0
  • OpenJDK9 Hotspot : synchronized 淺析

    摘要:前言網(wǎng)上各路大神總結(jié)過(guò)各種關(guān)于內(nèi)部實(shí)現(xiàn),看別人的文章總覺(jué)得不過(guò)癮,所以有了這篇文章,嘗試再扒一次的底褲數(shù)據(jù)結(jié)構(gòu)在分析源代碼之前需要了解相關(guān)概念,比如等,參考網(wǎng)絡(luò)上各種解說(shuō)或者之前系列文章,這里重點(diǎn)介紹一下,,每個(gè)在內(nèi)部都有一個(gè)的對(duì)象與之對(duì)應(yīng) 前言 網(wǎng)上各路大神總結(jié)過(guò)各種關(guān)于 hotspot jvm synchronized 內(nèi)部實(shí)現(xiàn),看別人的文章總覺(jué)得不過(guò)癮,所以有了這篇文章,嘗試再扒...

    Amio 評(píng)論0 收藏0
  • OpenJDK9 Hotspot:Zero 解釋器 初探

    摘要:準(zhǔn)備工作假設(shè)源代碼目錄為編譯時(shí)啟用了解釋器參考編譯和調(diào)試調(diào)用棧先在函數(shù)參考虛擬機(jī)入口中設(shè)斷點(diǎn),然后在的方法中設(shè)置斷點(diǎn)通過(guò)宏獲取當(dāng)前,然后創(chuàng)建第個(gè)棧幀,然后進(jìn)入解釋執(zhí)行字節(jié)碼 準(zhǔn)備工作 假設(shè) openjdk 源代碼目錄為 jdk9dev 編譯 openjdk 時(shí)啟用了 zero 解釋器(參考 OpenJDK9 Hotspot Mac OSX 編譯和調(diào)試) 調(diào)用棧 先在 JavaMai...

    zhangqh 評(píng)論0 收藏0
  • OpenJDK9 Hotspot Mac OSX 編譯和調(diào)試

    摘要:占用率太高,還出各種奇怪問(wèn)題,轉(zhuǎn)投調(diào)試安裝下載源代碼漫長(zhǎng)等待,中間無(wú)數(shù)次中斷安裝安裝可選如果要使用解釋器,需要安裝設(shè)置調(diào)試級(jí)別,設(shè)成可以提供更多的調(diào)試信息設(shè)置路徑 Intellij CLion CPU 占用率太高,還出各種奇怪問(wèn)題,轉(zhuǎn)投 Xcode 調(diào)試 hotspot 安裝 hg # brew install hg 下載 open jdk 9 源代碼 # hg clone http...

    zhichangterry 評(píng)論0 收藏0
  • OpenJDK9 Hotspot 虛擬機(jī)內(nèi)部對(duì)象內(nèi)存管理

    摘要:前言語(yǔ)言可以精確控制對(duì)象內(nèi)存分配,出于性能考慮框架系統(tǒng)程序基本都會(huì)自己造輪子開(kāi)發(fā)各種內(nèi)存管理模塊也不例外,它通過(guò)和方法的訪問(wèn)級(jí)別以及重載和方法來(lái)管理虛擬機(jī)內(nèi)部對(duì)象的內(nèi)存內(nèi)存管理相關(guān)的基類定義了幾個(gè)基類來(lái)作為大部分對(duì)象的基類顧名思義,它們只能 前言 C++ 語(yǔ)言可以精確控制對(duì)象內(nèi)存分配,出于性能考慮 C++ 框架 or 系統(tǒng)程序基本都會(huì)自己 造輪子 開(kāi)發(fā)各種內(nèi)存管理模塊. hotspot...

    W_BinaryTree 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<