Java並發之徹底搞懂偏向鎖定擴大為輕量級鎖

來源:互聯網
上載者:User

標籤:分析   set   ssi   cpp   force   擷取   oss   rpo   obj   

網上有許多講偏向鎖,輕量級鎖的文章,但對偏向鎖如何升級講的不夠明白,有些文章還相互矛盾,經過對jvm源碼(biasedLocking.cpp)的仔細分析和追蹤,基本升級過程有了一個清晰的過程,現將升級流程闡述如下:

     因為偏向鎖,鎖住對象時,會寫入對象頭相應的標識,我們先把對象頭(官方叫法為:Mark Word)的圖示如下(借用了網友的圖片):

      

    通過上面的圖片,我們可以知道,對象處於偏向鎖時,mark word中的偏向鎖標記為1,鎖標誌位為01;下面是分析過jvm源碼(biasedLocking.cpp)解析的偏向鎖定擴大流程(忽略一些細節),樣本中:線程1當前擁有偏向鎖對象,線程2是需要競爭到偏向鎖。

  1. 線程2來競爭鎖對象;
  2. 判斷當前對象頭是否是偏向鎖;
  3. 判斷擁有偏向鎖的線程1是否還存在;
  4. 線程1不存在,直接設定偏向鎖標識為0(線程1執行完畢後,不會主動去釋放偏向鎖);
  5. 使用cas替換偏向鎖線程ID為線程2,鎖不升級,仍為偏向鎖;
  6. 線程1仍然存在,暫停線程1;
  7. 設定鎖標誌位為00(變為輕量級鎖),偏向鎖為0;
  8. 從線程1的空閑monitor record中讀取一條,放至線程1的當前monitor record中;
  9. 更新mark word,將mark word指向線程1中monitor record的指標;
  10. 繼續執行線程1的代碼;
  11. 鎖定擴大為輕量級鎖;   
  12. 線程2自旋來擷取鎖對象;
   上面仍有一個問題,即如何判斷線程1已經不存在了?        仍然是分析完jvm源碼(thread.cpp)後,得到的如下結論:           (1) 線程執行start時,會將自己寫入一個thread_list中,這是一個linked結構,有pre和next節點;                        對應源碼位置:                               void Threads::add(JavaThread* p, bool force_daemon) {
  // The threads lock must be owned at this point
  assert_locked_or_safepoint(Threads_lock);
  // See the comment for this method in thread.hpp for its purpose and
  // why it is called here.
  p->initialize_queues();
  p->set_next(_thread_list);
  _thread_list = p;
  _number_of_threads++;
  oop threadObj = p->threadObj();
  bool daemon = true;
  // Bootstrapping problem: threadObj can be null for initial
  // JavaThread (or for threads attached via JNI)
  if ((!force_daemon) && (threadObj == NULL || !java_lang_Thread::is_daemon(threadObj))) {
        _number_of_non_daemon_threads++;
        daemon = false;
  }
  p->set_safepoint_visible(true);
  ThreadService::add_thread(p, daemon);
    // Possible GC point.
  Events::log(p, "Thread added: " INTPTR_FORMAT, p);
   }
           (2)線程執行完後,會將自己從thread list中清理掉(源碼位置: Threads::remove(this));       因此只需判斷thread list中是否存線上程1即可,判斷原始碼(位於biasedLocking.cpp中 )如下:             bool thread_is_alive = false; if (requesting_thread == biased_thread) {       thread_is_alive = true; } else {
     for (JavaThread* cur_thread = Threads::first(); cur_thread != NULL; cur_thread = cur_thread->next()) {
              if (cur_thread == biased_thread) {                    thread_is_alive = true;                    break;              }          }

Java並發之徹底搞懂偏向鎖定擴大為輕量級鎖

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.