最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中管理資源的引用隊(duì)列相關(guān)原理解析

 更新時(shí)間:2015年12月21日 16:20:40   作者:爪哇小博  
這篇文章主要介紹了Java中管理資源的引用隊(duì)列相關(guān)原理解析,涉及到Java的垃圾回收機(jī)制方面的知識(shí),需要的朋友可以參考下

當(dāng)對(duì)象改變其可達(dá)性狀態(tài)時(shí),對(duì)該對(duì)象的引用就可能會(huì)被置于引用隊(duì)列(reference queue)中。這些隊(duì)列被垃圾回收器用來(lái)與我們的代碼溝通有關(guān)對(duì)象可達(dá)性變化的情況。這些隊(duì)列是探測(cè)可達(dá)性變化的最佳方式,盡管我們也可以通過(guò)檢查get方法的返回值是不是null來(lái)探測(cè)對(duì)象的可達(dá)性變化。

  引用對(duì)象在構(gòu)造時(shí)可以與特定隊(duì)列建立關(guān)聯(lián)。Reference的每一個(gè)子類都提供了如下形式的構(gòu)造器:

  .public Strength Reference (T referent, ReferenceQueueq):該方法用給定的指稱對(duì)象創(chuàng)建新的引用對(duì)象,并且把該引用對(duì)象注冊(cè)到給定的隊(duì)列中。弱引用和軟引用在垃圾回收器確定它們的指稱對(duì)象進(jìn)人它們所表示的特定可達(dá)性狀態(tài)之后,就會(huì)被插人到隊(duì)列中,并且這兩種引用在插人隊(duì)列前都會(huì)被清除。虛引用也會(huì)在垃圾回收器確定它的指稱對(duì)象進(jìn)入虛可達(dá)狀態(tài)之后,被插入到隊(duì)列中,但是它們不會(huì)被清除。一旦引用對(duì)象被垃圾回收器插人到隊(duì)列中,其get方法的返回值就肯定會(huì)是null,因此該對(duì)象就再也不能復(fù)活了。

  將引用對(duì)象注冊(cè)到引用隊(duì)列中并不會(huì)創(chuàng)建隊(duì)列和引用對(duì)象之間的引用。如果我們的引用對(duì)象本身變成了不可達(dá)的,那么它就不能插人隊(duì)列了。因此我們的應(yīng)用需要保持對(duì)所有引用對(duì)象的強(qiáng)引用。

  ReferenceQueue類提供了三個(gè)用來(lái)移除隊(duì)列中引用的方法:

  1.   .public Reference < ? extends下>poll ():用于移除并返回該隊(duì)列中的下一個(gè)引用對(duì)象,如果隊(duì)列為空,則返回null.
  2.   .public Referenceremove ()throws InterruptedException:用于移除并返回該隊(duì)列中的下一個(gè)引用對(duì)象,該方法會(huì)在隊(duì)列返回可用引用對(duì)象之前一直阻塞。
  3.   .public Referenceremove (long timeout) throws interrupte-dException:用于移除并返回隊(duì)列中的下一個(gè)引用對(duì)象。該方法會(huì)在隊(duì)列返回可用引用對(duì)象之前一直阻塞,或者在超出指定超時(shí)后結(jié)束。如果超出指定超時(shí),則返回null.如果指定超時(shí)為0,意味著將無(wú)限期地等待。

  poll方法使得線程可以查詢某個(gè)引用是否在隊(duì)列中,并且在該引用存在于隊(duì)列中時(shí)執(zhí)行特定的動(dòng)作。remove方法可以處理更復(fù)雜(更少見(jiàn))的情況,在該方法中有一個(gè)專門的線程負(fù)責(zé)從隊(duì)列中移除引用,并執(zhí)行恰當(dāng)?shù)膭?dòng)作。這些方法的阻塞行為和object.wait中定義的阻塞行為相同。對(duì)于特定的引用,我們可以通過(guò)其isEnqueued方法來(lái)查詢它是否在隊(duì)列中,也可以通過(guò)調(diào)用其enqueue方法將其強(qiáng)制插入到隊(duì)列中,但是通常這種插人是由垃圾回收器完成的。

  引用隊(duì)列中的虛引用可以用來(lái)確定對(duì)象何時(shí)可以被回收。我們不可能通過(guò)虛引用來(lái)訪問(wèn)任何對(duì)象,即使該對(duì)象通過(guò)其他方式是可達(dá)的也是如此,因?yàn)樘撘玫膅et方法總是返回null,事實(shí)上,用虛引用來(lái)查找要回收的對(duì)象是最安全的方法,因?yàn)槿跻煤蛙浺迷趯?duì)象可終結(jié)之后會(huì)被插人到隊(duì)列中,而虛引用是在指稱對(duì)象被終結(jié)之后插人到隊(duì)列中的,即在該對(duì)象可以執(zhí)行某些操作的最后時(shí)刻之后插人隊(duì)列的,所以它是絕對(duì)安全的。如果可以的話,應(yīng)該總是使用虛引用,因?yàn)槠渌脮?huì)存在finalize方法使用可終結(jié)對(duì)象的可能性。

  考慮一個(gè)資源管理器的例子,它可以控制外部資源集合的訪問(wèn)。對(duì)象可以請(qǐng)求訪問(wèn)某項(xiàng)外部資源,并且直至操作完成才結(jié)束訪問(wèn),在此之后,它們應(yīng)該將所用資源返回給資源管理器。如果這項(xiàng)資源是共享的,它的使用權(quán)就會(huì)在多個(gè)對(duì)象之間傳遞,甚至可能會(huì)在多個(gè)線程之間傳遞,因此我們很難確定哪個(gè)對(duì)象是這項(xiàng)資源最后的使用者,從而也就很難確定哪段代碼將負(fù)責(zé)返回這項(xiàng)資源。為了處理這種情況,資源管理器可以通過(guò)將資源關(guān)聯(lián)到被稱為鍵( key)的特殊對(duì)象上,實(shí)現(xiàn)這項(xiàng)資源的自動(dòng)回收。只要鍵對(duì)象是可達(dá)的,我們就認(rèn)為這項(xiàng)資源還在使用中;只要鍵對(duì)象可以被當(dāng)作垃圾回收,這項(xiàng)資源就會(huì)被自動(dòng)釋放。下面的代碼是對(duì)上述資源的抽象表示:

  interface Resource{

  void use(Object key, Object…args);

  void release();

  }

  當(dāng)獲得某項(xiàng)資源時(shí),其鍵對(duì)象必須提供給資源管理器。對(duì)于交還的Resource實(shí)例,只有在它得到了其對(duì)應(yīng)的鍵時(shí),才可以使用這項(xiàng)資源。這樣就可以確保在鍵被回收之后,它所對(duì)應(yīng)的資源就不能再被使用了,即便表示這項(xiàng)資源的Resource對(duì)象本身可能仍然是可達(dá)的。請(qǐng)注意,Resource對(duì)象并未存儲(chǔ)對(duì)鍵對(duì)象的強(qiáng)引用,這一點(diǎn)很重要,因?yàn)檫@可以防止鍵對(duì)象變?yōu)椴豢蛇_(dá)的,從而造成資源不能收回。Resource的實(shí)現(xiàn)可以嵌套在資源管理器中:

  private static class ResourceImpl implements Resource{

  int keyHash;

  boolean needsRelease=false

  ResourceImpl(Object key){

  keyHash=System.identityHashCode(key);

  //=set up the external resource

  needsRelease=true; }

  public void use(Object key,Object... args){

  if (System.identityHashCode(key)!=keyHash)

  throw new IlleqalArgumentException("wrong key"

  //...use the resource

  }

  public synchronized void release(){

  if (needsRelease){

  needsRelease=false:

  //=release the resource

  }

  }

  }

  在資源被創(chuàng)建時(shí)就存儲(chǔ)了鍵對(duì)象的散列碼,并且無(wú)論何時(shí)調(diào)用use方法,它都會(huì)檢查是否提供了相同的鍵。對(duì)資源的實(shí)際使用可能還需要進(jìn)行同步,但是為了簡(jiǎn)單起見(jiàn),我們?cè)谶@里把它們省略了。release方法負(fù)責(zé)釋放資源,它可以由資源的使用者在使用結(jié)束之后直接調(diào)用,也可 以由資源管理器在鍵對(duì)象不再被引用時(shí)調(diào)用。因?yàn)槲覀儗⑹褂锚?dú)立的線程來(lái)監(jiān)視引用隊(duì)列,所以release方法必須是synchronized的,并且必須允許多次調(diào)用。

  實(shí)際的資源管理器具有如下形式:

  public final class ResourceManager{

  final ReferenceQueue

                            
  鍵對(duì)象可以是任意對(duì)象,與讓資源管理器分配鍵對(duì)象相比,這賦予了資源使用者極大的靈活性。在調(diào)用getResource方法時(shí),會(huì)創(chuàng)建一個(gè)新的Resource工mpl對(duì)象,同時(shí)會(huì)把提供給該方法的鍵傳遞給這個(gè)新的ResourceImpl對(duì)象。然后會(huì)創(chuàng)建一個(gè)虛引用,其指稱對(duì)象就是傳遞給該方法的鍵,之后這個(gè)虛引用會(huì)被插人到資源管理器的引用隊(duì)列中。最后所創(chuàng)建的虛引用和引用對(duì)象會(huì)被存儲(chǔ)到映射表中,這個(gè)映射表有兩個(gè)用途:一是保持所有的虛引用對(duì)象都是可達(dá)的,二是可以提供便捷的方法來(lái)查詢每個(gè)虛引用所關(guān)聯(lián)的實(shí)際的Resource對(duì)象。(另一種方式是子類化PhantomReference并將Resource對(duì)象存在一個(gè)字段中。)

  如果鍵對(duì)象變成了不可達(dá)的,那么資源管理器會(huì)使用獨(dú)立的“收割機(jī)”(reaper)線程來(lái)處理資源。shutdown方法通過(guò)終止收割機(jī)線程(以響應(yīng)中斷)從而導(dǎo)致getResource方法拋出Ille-llleStateException異常來(lái)“關(guān)閉”資源管理器。在這個(gè)簡(jiǎn)單的設(shè)計(jì)中,任何在資源管理器關(guān)閉之后插人隊(duì)列的引用都不會(huì)得到處理。實(shí)際的收割機(jī)線程如下:

  class ReaperThread extends Thread{

  public void run(){

  //run until interrupted

  while (true){

  try{

  Reference ref=queue.remove();

  Resource res=null;

  synchronized(ResourceManager.this){

  res=refs.get(ref);

  refs . remove(ref);

  }

  res .release();

  ref.clear();

  }

  catch (InterruptedException ex){

  break;//all done

  }

  }

  }

  }

  ReaperThread是內(nèi)部類,并且給定的收割機(jī)線程會(huì)一直運(yùn)行,直至與其相關(guān)聯(lián)的資源管理器關(guān)閉。該線程會(huì)在remove方法上阻塞,直至與特定鍵相關(guān)聯(lián)的虛引用被插人到引用隊(duì)列中為止。這個(gè)虛引用可以從映射表中獲取對(duì)Resource對(duì)象的引用,然后這一項(xiàng)“鍵一引用”對(duì)將會(huì)從映射表中移除。緊接著,在Resource對(duì)象上調(diào)用其release方法來(lái)釋放這項(xiàng)資源。最后,

  虛引用被清除,使得鍵可以被回收。

  作為一種替代使用獨(dú)立線程的方案,凡是在引用隊(duì)列上調(diào)用poll方法并釋放其鍵已經(jīng)變?yōu)椴豢蛇_(dá)的所有資源的操作都可以用getResourc“方法來(lái)替代,shutdow”方法也可以用來(lái)執(zhí)行最后的poll操作。而資源管理器的語(yǔ)義將依賴于實(shí)際的資源類型和資源使用的模式。

  使用引用隊(duì)列的設(shè)計(jì)與直接使用終結(jié)(特別是使用虛引用)的設(shè)計(jì)相比,要可靠得多。但是我們要記住,對(duì)于引用對(duì)象插入到引用隊(duì)列中的確切時(shí)間和位置都是不能確定的,我們也不能確定在應(yīng)用程序終止的時(shí)候,所有可插人的引用是否都匕經(jīng)插人到了引用隊(duì)列中。如果我們需要確保所有資源在應(yīng)用程序終止之前都能夠被釋放掉,就必須要安裝必要的關(guān)閉掛鉤或者使用由應(yīng)用程序定義的其他協(xié)議來(lái)確保實(shí)現(xiàn)這一點(diǎn)。

相關(guān)文章

  • Java必踩的坑之方法中形參、實(shí)參傳遞

    Java必踩的坑之方法中形參、實(shí)參傳遞

    這篇文章主要給大家介紹了關(guān)于Java必踩的坑之方法中形參、實(shí)參傳遞的相關(guān)資料,以及Java 形參和實(shí)參的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • Java的堵塞隊(duì)列BlockingQueue詳解

    Java的堵塞隊(duì)列BlockingQueue詳解

    這篇文章主要介紹了Java的堵塞隊(duì)列BlockingQueue詳解,阻塞隊(duì)列常用于生產(chǎn)者和消費(fèi)者的場(chǎng)景,生產(chǎn)者是向隊(duì)列里添加元素的線程,消費(fèi)者是從隊(duì)列里取元素的線程,需要的朋友可以參考下
    2023-12-12
  • JAVA泛型之泛型方法的定義和使用方式

    JAVA泛型之泛型方法的定義和使用方式

    這篇文章主要介紹了JAVA泛型之泛型方法的定義和使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • java實(shí)現(xiàn)請(qǐng)求緩沖合并的示例代碼

    java實(shí)現(xiàn)請(qǐng)求緩沖合并的示例代碼

    我們對(duì)外提供了一個(gè)rest接口給第三方業(yè)務(wù)進(jìn)行調(diào)用,但是由于第三方框架限制,導(dǎo)致會(huì)發(fā)送大量相似無(wú)效請(qǐng)求,這篇文章主要介紹了java實(shí)現(xiàn)請(qǐng)求緩沖合并,需要的朋友可以參考下
    2024-04-04
  • Java定時(shí)任務(wù)取消的示例代碼

    Java定時(shí)任務(wù)取消的示例代碼

    java定時(shí)任務(wù)如何取消,并比如,我之前想每周二晚上6點(diǎn)自動(dòng)生成一條devops流水線,現(xiàn)在我想停掉,下面給大家分享java定時(shí)任務(wù)取消的示例代碼,演示如何創(chuàng)建一個(gè)每周二晚上6點(diǎn)自動(dòng)生成一條devops流水線的定時(shí)任務(wù),感興趣的朋友一起看看吧
    2024-02-02
  • spring boot如何實(shí)現(xiàn)切割分片上傳

    spring boot如何實(shí)現(xiàn)切割分片上傳

    這篇文章主要介紹了spring boot如何實(shí)現(xiàn)切割分片上傳,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java使用正則表達(dá)式驗(yàn)證用戶名和密碼的方法

    Java使用正則表達(dá)式驗(yàn)證用戶名和密碼的方法

    這篇文章主要介紹了Java使用正則表達(dá)式驗(yàn)證用戶名和密碼的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Mybatis攔截器實(shí)現(xiàn)一種百萬(wàn)級(jí)輕量分表方案

    Mybatis攔截器實(shí)現(xiàn)一種百萬(wàn)級(jí)輕量分表方案

    這篇文章主要介紹了Mybatis攔截器實(shí)現(xiàn)一種百萬(wàn)級(jí)輕量分表方案,需要的朋友可以參考下
    2024-02-02
  • SpringBoot快速集成jxls-poi(自定義模板,支持本地文件導(dǎo)出,在線文件導(dǎo)出)

    SpringBoot快速集成jxls-poi(自定義模板,支持本地文件導(dǎo)出,在線文件導(dǎo)出)

    這篇文章主要介紹了SpringBoot快速集成jxls-poi(自定義模板,支持本地文件導(dǎo)出,在線文件導(dǎo)出),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • IDEA?2021.3?使用及idea2021.3.1激活使用方法

    IDEA?2021.3?使用及idea2021.3.1激活使用方法

    IDEA?全稱?IntelliJ?IDEA,是java語(yǔ)言開(kāi)發(fā)的集成環(huán)境,IntelliJ在業(yè)界被公認(rèn)為最好的java開(kāi)發(fā)工具之一,今天通過(guò)本文給大家介紹idea2021.3.1激活及使用教程,感興趣的朋友一起看看吧
    2022-01-01

最新評(píng)論

阜康市| 沙湾县| 蚌埠市| 武强县| 黄大仙区| 大城县| 民和| 遵义市| 翁源县| 柳河县| 涿鹿县| 德江县| 定陶县| 乌兰县| 徐闻县| 鄄城县| 东乌珠穆沁旗| 兴仁县| 涟源市| 吉木萨尔县| 黑山县| 南投市| 张家口市| 石阡县| 丹凤县| 闽侯县| 新河县| 库伦旗| 海盐县| 宁国市| 宁都县| 大邑县| 洛扎县| 宝兴县| 莱阳市| 平度市| 淄博市| 兰溪市| 砚山县| 吉隆县| 丹阳市|