欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳談鎖和監(jiān)視器之間的區(qū)別_Java并發(fā)

 更新時間:2017年06月18日 10:07:38   投稿:jingxian  
下面小編就為大家?guī)硪黄斦勬i和監(jiān)視器之間的區(qū)別_Java并發(fā)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

在面試中你可能遇到過這樣的問題:鎖(lock)和監(jiān)視器(monitor)有什么區(qū)別?

嗯,要回答這個問題,你必須深入理解Java的多線程底層是如何工作的。

簡短的答案是,鎖為實現(xiàn)監(jiān)視器提供必要的支持。詳細(xì)答案如下。

鎖(lock)

邏輯上鎖是對象內(nèi)存堆中頭部的一部分?jǐn)?shù)據(jù)。JVM中的每個對象都有一個鎖(或互斥鎖),任何程序都可以使用它來協(xié)調(diào)對對象的多線程訪問。如果任何線程想要訪問該對象的實例變量,那么線程必須擁有該對象的鎖(在鎖內(nèi)存區(qū)域設(shè)置一些標(biāo)志)。所有其他的線程試圖訪問該對象的變量必須等到擁有該對象的鎖有的線程釋放鎖(改變標(biāo)記)。

一旦線程擁有一個鎖,它可以多次請求相同的鎖,但是在其他線程能夠使用這個對象之前必須釋放相同數(shù)量的鎖。如果一個線程請求一個對象的鎖三次,如果別的線程想擁有該對象的鎖,那么之前線程需要 “釋放”三次鎖。

Java中顯示鎖的使用語法如下:

…
private Lock bankLock = new ReentrantLock();
…
 public double getTotalBalance()
  {
   bankLock.lock();
   try
   {
     double sum = 0;

     for (double a : accounts)
      sum += a;

     return sum;
   }
   finally
   {
     bankLock.unlock();
   }
  }

1) 鎖用來保護(hù)代碼片段,任何時刻只能有一個線程執(zhí)行被保護(hù)的代碼。

2) 鎖可以管理試圖進(jìn)入被保護(hù)代碼的線程

3) 鎖可以擁有一個或者多個相關(guān)的條件對象

4) 每個條件對象管理那些已經(jīng)進(jìn)入被保護(hù)的代碼段,但還不能運(yùn)行的線程

Lock和Condition接口為程序設(shè)計人員提供了高度的鎖定控制。然后大多數(shù)情況下,并不需要這樣的控制,并且可以使用一種嵌入Java語言的內(nèi)部機(jī)制。從1.0版本開始,Java中的每一個對象都有一個內(nèi)部鎖。如果一個方法用synchronized關(guān)鍵字聲明,那么對象的鎖將保護(hù)整個方法。也就說,要調(diào)用該方法,線程必須獲得內(nèi)部的對象鎖。

內(nèi)部鎖的一般用法如下:

public synchronized void transfer(int from, int to, double amount) throws InterruptedException
  {
   while (accounts[from] < amount)
     wait();
   System.out.print(Thread.currentThread());
   accounts[from] -= amount;
   System.out.printf(" %10.2f from %d to %d", amount, from, to);
   accounts[to] += amount;
   System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
   notifyAll();
  }

可以看到,用synchronized關(guān)鍵字來編寫代碼簡潔得多。當(dāng)然要理解這一代碼,你必須了解每一個對象有一個內(nèi)部鎖,并且該鎖有一個內(nèi)部條件。由鎖來管理那些試圖進(jìn)入synchronized方法的線程,由條件來管理那些調(diào)用wait的線程

然而,講了這么多,實際上推薦最好優(yōu)先使用BlockQueue,Excutor,同步集合等,然后再是synchronized關(guān)鍵字,最才是Lock/Condition

監(jiān)視器(Monitor)

監(jiān)視器是一中同步結(jié)構(gòu),它允許線程同時互斥(使用鎖)和協(xié)作,即使用等待集(wait-set)使線程等待某些條件為真的能力。

互斥

使用比較形象的說明,監(jiān)視器就像一個包含一個特殊房間(對象實例)的建筑物,每次只能占用一個線程。這個房間通常包含一些需要防止并發(fā)訪問的數(shù)據(jù)。從一個線程進(jìn)入這個房間到它離開的時間,它可以獨(dú)占訪問房間中的任何數(shù)據(jù)。進(jìn)入監(jiān)控的建筑被稱為“進(jìn)入監(jiān)控監(jiān)視器。”進(jìn)入建筑內(nèi)部特殊的房間叫做“獲取監(jiān)視器”。房間占領(lǐng)被稱為“擁有監(jiān)視器”,離開被稱為“釋放監(jiān)視器。”讓整個建筑被稱為“退出監(jiān)視器。”

當(dāng)一個線程訪問受保護(hù)的數(shù)據(jù)(進(jìn)入特殊的房間)時,它首先在建筑物接收(entry-set)中排隊。如果沒有其他線程在等待(擁有監(jiān)視器),線程獲取鎖并繼續(xù)執(zhí)行受保護(hù)的代碼。當(dāng)線程完成執(zhí)行時,它釋放鎖并退出大樓(退出監(jiān)視器)。

如果當(dāng)一個線程到達(dá)并且另一個線程已經(jīng)擁有監(jiān)視器時,它必須在接收隊列中等待(entry-set)。當(dāng)當(dāng)前所有者退出監(jiān)視器時,新到達(dá)的線程必須與在入口集中等待的其他線程競爭。只有一個線程能贏得競爭并擁有鎖。

這里沒有wait-set的事。

合作

一般來說,只有當(dāng)多個線程共享數(shù)據(jù)或其他資源時,互斥才是重要的。如果兩個線程不處理任何公共數(shù)據(jù)或資源,它們通常不能互相干擾,也不需要以互斥的方式執(zhí)行。盡管互斥有助于防止線程在共享數(shù)據(jù)時互相干擾,但合作有助于線程共同努力實現(xiàn)一些共同目標(biāo)。

合作在當(dāng)一個線程需要的數(shù)據(jù)改變?yōu)樵谝粋€特定的狀態(tài)時很重要,另一個線程負(fù)責(zé)將數(shù)據(jù)該入狀態(tài),如生產(chǎn)者/消費(fèi)者的問題,讀線程需要緩沖去在一個“不空”的狀態(tài)才可以從緩沖區(qū)中讀取任何數(shù)據(jù)。如果讀線程發(fā)現(xiàn)緩沖區(qū)為空,則必須等待。寫線程負(fù)責(zé)用數(shù)據(jù)填充緩沖區(qū)。一旦寫入線程完成了更多的寫入操作,讀線程可以進(jìn)行更多的讀取。它有時也稱為“Wait and Notify”或“Signal and Continue”監(jiān)視器,因為它保留對監(jiān)視器的所有權(quán),并繼續(xù)執(zhí)行監(jiān)視區(qū)域(如果需要的話繼續(xù))。在稍后的時間內(nèi),通知線程釋放監(jiān)視器,等待線程重新恢復(fù)擁有鎖。

這種合作需要entry-setwait-set.。下面的圖表將有助于您理解這種合作。

上圖顯示監(jiān)視器為三個矩形。在該中心,一個大矩形包含一個線程,即監(jiān)視器的所有者。在左邊,一個小矩形包含entry set。在右邊,另一個小矩形包含wait set。

監(jiān)視器是由Per Brich Hansen和Tony Hoare提出的概念,Java以不精確的方式采用了它,也就是Java中的每個對象有一個內(nèi)部的鎖和內(nèi)部條件。如果一個方法用synchronized關(guān)鍵字聲明,那么,它表現(xiàn)的就像一個監(jiān)視器方法。通過wait/notifyAll/nofify來訪問條件變量

我希望上面內(nèi)容將有助于你更深入地了解Java多線程,歡迎提出任何問題。

以上這篇詳談鎖和監(jiān)視器之間的區(qū)別_Java并發(fā)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中的CopyOnWriteArrayList原理詳解

    Java中的CopyOnWriteArrayList原理詳解

    這篇文章主要介紹了Java中的CopyOnWriteArrayList原理詳解,如源碼所示,CopyOnWriteArrayList和ArrayList一樣,都在內(nèi)部維護(hù)了一個數(shù)組,操作CopyOnWriteArrayList其實就是在操作內(nèi)部的數(shù)組,需要的朋友可以參考下
    2023-12-12
  • Java代碼中與Lua相互調(diào)用實現(xiàn)詳解

    Java代碼中與Lua相互調(diào)用實現(xiàn)詳解

    這篇文章主要為大家介紹了Java代碼中與Lua相互調(diào)用實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • springboot3.X版本集成mybatis遇到的問題及解決

    springboot3.X版本集成mybatis遇到的問題及解決

    在將SpringBoot3.X版本與MyBatis集成時,直接參考基于SpringBoot2.X的配置方法會導(dǎo)致各種報錯,尤其是無法注入mapper的bean問題,這主要是因為SpringBoot3.X版本需要搭配MyBatis3.0.3及以上版本才能正常工作,通過更新maven配置至MyBatis3.0.3版本,可以解決這一問題
    2024-09-09
  • Spring Boot 中application.yml與bootstrap.yml的區(qū)別

    Spring Boot 中application.yml與bootstrap.yml的區(qū)別

    其實yml和properties文件是一樣的原理,且一個項目上要么yml或者properties,二選一的存在。這篇文章給大家介紹了Spring Boot 中application.yml與bootstrap.yml的區(qū)別,感興趣的朋友一起看看吧
    2018-04-04
  • Spring定義Bean范圍的三種方式

    Spring定義Bean范圍的三種方式

    在Spring框架中,Bean的作用域(scope)決定了一個Bean實例的生命周期和可見性,Spring支持多種作用域,最常用的是singleton和prototype,此外還有request、session等Web應(yīng)用相關(guān)的特定作用域,本文給大家介紹了Spring定義Bean范圍的三種方式,需要的朋友可以參考下
    2024-08-08
  • maven install報錯中程序包xxx不存在的問題解決

    maven install報錯中程序包xxx不存在的問題解決

    本文主要介紹了maven install報錯中程序包xxx不存在的問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 官方詳解HDFS?Balancer工具主要調(diào)優(yōu)參數(shù)

    官方詳解HDFS?Balancer工具主要調(diào)優(yōu)參數(shù)

    這篇文章主要為大家介紹了HDFS?Balancer工具主要調(diào)優(yōu)參數(shù)的?官方詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Spring?Boot整合Kafka教程詳解

    Spring?Boot整合Kafka教程詳解

    這篇文章主要為大家介紹了Spring?Boot整合Kafka教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 在Java中使用下劃線分隔數(shù)的字面值的用法講解

    在Java中使用下劃線分隔數(shù)的字面值的用法講解

    這篇文章主要介紹了在Java中使用下劃線分隔數(shù)字的字面值的用法講解,這是Java7以后加入的新特性,需要的朋友可以參考下
    2016-03-03
  • SWT(JFace) 體驗之FontRegistry

    SWT(JFace) 體驗之FontRegistry

    測試代碼如下:
    2009-06-06

最新評論