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

java中的Reference類型用法說明

 更新時間:2020年09月27日 10:03:43   作者:嘖嘖嘖嘖zezezeze  
這篇文章主要介紹了java中的Reference類型用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

本文簡要總結(jié)java中的Reference類型。

最近在研讀jdk并發(fā)框架,其中AQS是重點,由于我打破砂鍋問到底的輕微強迫癥,google了AQS作者Doug Lea的論文原文[The java.util.concurrent Synchronizer Framework],有興趣的同學(xué)可以自行下載。其中談到設(shè)計同步框架的核心是選擇一個嚴(yán)格意義上的FIFO隊列,作為阻塞線程隊列并對其進行維護。

對此主要由兩種選擇,一個是MCS鎖,另一個時CLH鎖。因為CLH鎖比MCS對取消和超時的處理更方便,所以AQS就選擇將CLH鎖作為基礎(chǔ)對其進行改進。于是我又打算先弄懂什么是CLH鎖,在網(wǎng)上搜索了一圈之后找到很多人對CLH鎖進行了java實現(xiàn),實現(xiàn)中用到了ThreadLocal類型,于是我發(fā)現(xiàn)我好像對ThreadLocal也不太熟,于是去看openjdk的源碼,又發(fā)現(xiàn)ThreadLocal的內(nèi)部類ThreadLocalMap中的Entry是繼承自WeakReference,好了,既然這幾個我好像都沒弄得很明白過,所以我決定先了解一下Reference。

在我們平時開發(fā)過程中很少會遇到需要與各種不同類型的reference打交道的時候,所以很多時候我們在自己寫的代碼中很少會碰到需要使用不同的reference類型,可能很多人也會向我這樣,想要深入學(xué)習(xí)一下jdk源碼或者其他某些框架的源碼的時候才會看到諸如WeakReference這樣的類型。

問題

假設(shè)在一個應(yīng)用中,需要從一個名為test的數(shù)據(jù)庫表中獲取數(shù)據(jù)。但凡有點經(jīng)驗的開發(fā)人員都會避免應(yīng)用獲取相同的數(shù)據(jù)每次都去查詢數(shù)據(jù)庫,因為I/O操作過去頻繁勢必會降低應(yīng)用性能。

顯然,我們首先想到的就是使用緩存。應(yīng)用首先查詢緩存,如果需要的數(shù)據(jù)存在直接拿來用就好;如果緩存未命中,才去數(shù)據(jù)庫查詢,并且把查詢到的數(shù)據(jù)放入緩存,以便下次應(yīng)用發(fā)起相同請求時可以直接從緩存獲取數(shù)據(jù)而不用再次去數(shù)據(jù)庫查詢。

使用緩存會提高性能嗎?

答案是這需要根據(jù)具體情況分析,如果從test獲取需要緩存的數(shù)據(jù)量較少,使用緩存會非常合適且一定會提升性能。但假若需要從test表查詢放到緩存里的數(shù)據(jù)量非常大,那就會出現(xiàn)一個問題:由于數(shù)據(jù)量過大可能會導(dǎo)致內(nèi)存不足,而不單單是提升性能了。假如說把表中所有數(shù)據(jù)都放入緩存,那么緩存的可能會占據(jù)大部分jvm的內(nèi)存或者索性直接產(chǎn)生一個OOM錯誤。

解決方案

最佳的方案是如果我們可以創(chuàng)造一種可以按需擴展和收縮的動態(tài)緩存,當(dāng)我們的數(shù)據(jù)量需要而內(nèi)存充裕的時候可以適當(dāng)增加,但內(nèi)存不足是可以按不同方案對其進行回收。

目的

這里引出的一個問題,就是為什么要在Java中使用不同類型的reference?我們的應(yīng)用在運行過程中會產(chǎn)生很多對象,這些對象駐留在內(nèi)存中,它們大小不同,重要性不同,使用頻率不同,生命周期不同,比如有些對象只要應(yīng)用啟動就一直存活直到應(yīng)用停止,而有些對象生命周期與創(chuàng)建它的線程相同,還有些對象只作臨時變量短時間就消亡,再比如某些緩存數(shù)據(jù),內(nèi)存充裕的時候可以存活,內(nèi)存不足的時候可能需要被首先犧牲被回收,所以很容易想象對于不同的對象,我們希望對他們的創(chuàng)建銷毀采取不同的策略,可是不幸的是java不像C一樣可以由開發(fā)者決定對象的析構(gòu)銷毀,而是將管理內(nèi)存的活統(tǒng)一交給了jvm進行g(shù)c,但jvm顯然不知道這些對象的區(qū)別。

于是設(shè)計者們在java 1.2加入了reference,使jvm可以對不同的reference對象采取不同的回收策略以達(dá)到提高應(yīng)用性能的目的。

java.lang.ref 包

實際上java.lang.ref包中就有以下幾種不同的reference類型,分別是:

StrongReference

SoftReference

WeakReference

PhantomReference

FinalReference

StrongReference

我們發(fā)現(xiàn)在類圖中我們并沒有發(fā)現(xiàn) StrongReference 類型,原因是我們平時寫的代碼基本上都是 StrongReference 。我們最常的創(chuàng)建對象方式就是 new 一個對象,然后將其賦值給一個聲明為這個對象的類型及其父類的引用。如果對象有一個 StrongReference ,那么這個對象將不會被gc回收。

舉例

HelloWorld hello = new HelloWorld();

這里 hello 就是一個 HelloWorld 對象的 StrongReference。

SoftReference

如果一個對象沒有 StrongReference 但存在一個 SoftReference ,那么 gc 將會在虛擬機需要釋放一些內(nèi)存的時候回收這個對象。可以通過對對象的 SoftReference 調(diào)用 get() 方法獲取該對象。如果這個對象沒有被 gc 回收,則返回此對象,否則返回 null 。

WeakReference

如果一個對象沒有 StrongReference 但有存在一個 WeakReference ,那么 gc 將會在下一次運行時對其進行回收,哪怕虛擬機的內(nèi)存還足夠多。

PhantomReference 與 FinalReference

如果某個對象沒有以上這些類型的引用,那么它可能有一個 PhantomReference 。PhantomReference 不能用于直接訪問對象。調(diào)用 get() 方法都會返回 null 。

FinalReference 與虛擬機密切相關(guān),這里先挖個坑,下次再具體解析。

對象可達(dá)性判斷

當(dāng)前主流java虛擬機都是采用 GC Roots Tracing 算法,比如 Sun 的 Hotspot 虛擬機便是采用該算法。java虛擬機進行g(shù)c時,判斷一個對象的被引用情況決定是否回收,都是從根節(jié)點引用(Root set of Reference)開始標(biāo)識可達(dá)路徑的。對于某個對象可能會存在其多個引用,且這多個引用的類型不同。

如下圖所示:

Root Tracing 算法根據(jù)以下兩個原則標(biāo)記對象的可達(dá)性:

單一路徑中,以最弱的引用為準(zhǔn)

多路徑中,以最強的引用為準(zhǔn)

如上圖所示,對對象4存在3條引用路徑:(1)(4),(2)(5),(3)(6)。那么從根對象到對象4的最強引用時(2)(5),因為(2)和(5)都是強引用。如果對象4僅存在一條(1)(4)引用,那么對它的引用就是最弱的引用為準(zhǔn),也就是 SoftReference ,對象4就是 softly-reachable 對象。

不同類型 reference java 代碼舉例

package com.example.reference;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
public class ReferenceExample {
  private String status ="Hi I am active";
  public String getStatus() {
    return status;
  }
  public void setStatus(String status) {
    this.status = status;
  }
  @Override
  public String toString() {
    return "ReferenceExample [status=" + status + "]";
  }
  public void strongReference()
  {
    ReferenceExample ex = new ReferenceExample();
    System.out.println(ex);
  }
  public void softReference()
  {
    SoftReference<ReferenceExample> ex = new SoftReference<ReferenceExample>(getRefrence());
    System.out.println("Soft refrence :: " + ex.get());
  }
  public void weakReference()
  {
    int counter=0;
    WeakReference<ReferenceExample> ex = new WeakReference<ReferenceExample>(getRefrence());
    while(ex.get()!=null)
    {
      counter++;
      System.gc();
      System.out.println("Weak reference deleted after:: " + counter + ex.get());
    }
  }
  public void phantomReference() throws InterruptedException
  {
    final ReferenceQueue queue = new ReferenceQueue();
    PhantomReference<ReferenceExample> ex = new PhantomReference<ReferenceExample>(getRefrence(),queue);
    System.gc();
    queue.remove();
    System.out.println("Phantom reference deleted after");
  }
  private ReferenceExample getRefrence()
  {
    return new ReferenceExample();
  }
  public static void main(String[] args) {
    ReferenceExample ex = new ReferenceExample();
    ex.strongReference();
    ex.softReference();
    ex.weakReference();
    try {
      ex.phantomReference();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output :
ReferenceExample [status=Hi I am active]
Soft refrence :: ReferenceExample [status=Hi I am active]
Weak reference deleted after:: 1null
Phantom reference deleted after

總結(jié)

通過對以上各類型的 reference 介紹可以發(fā)現(xiàn)其實 reference 主要是用來與虛擬機 gc 進行交互,使得虛擬機根據(jù)對象的不同引用類型,對其采用不同的內(nèi)存回收策略。

strong 引用的對象正常情況下不會被回收,soft 引用的對象會在出現(xiàn) OOM 錯誤之前被回收,而 weak 引用的對象在下一次 gc 的時候就會被回收,對 reference 的基本理解就差不多了。

至于 PhantomReference 與 FinalReference 下次再講。

以上這篇java中的Reference類型用法說明就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 通過實例解析Spring組合注解與元注解

    通過實例解析Spring組合注解與元注解

    這篇文章主要介紹了通過實例解析Spring組合注解與元注解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • Spring?Boot整合Zookeeper實現(xiàn)分布式鎖的場景分析

    Spring?Boot整合Zookeeper實現(xiàn)分布式鎖的場景分析

    這篇文章主要介紹了Spring?Boot整合Zookeeper實現(xiàn)分布式鎖,zk實現(xiàn)分布式鎖完全是依靠zk節(jié)點類型當(dāng)中的臨時序號節(jié)點來實現(xiàn)的,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • 解決RestTemplate 請求接收自定義400+ 或500+錯誤

    解決RestTemplate 請求接收自定義400+ 或500+錯誤

    這篇文章主要介紹了解決RestTemplate 請求接收自定義400+ 或500+錯誤,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot中Redis自動配置的介紹、原理和使用詳解

    SpringBoot中Redis自動配置的介紹、原理和使用詳解

    這篇文章主要介紹了SpringBoot中Redis自動配置的介紹、原理和使用詳解,Redis是一種高性能的鍵值對存儲數(shù)據(jù)庫,它支持多種數(shù)據(jù)結(jié)構(gòu)和豐富的功能,如緩存、消息隊列、計數(shù)器、分布式鎖等,需要的朋友可以參考下
    2023-08-08
  • Java8 Optional的詳細(xì)使用教程

    Java8 Optional的詳細(xì)使用教程

    這篇文章主要給大家介紹了關(guān)于Java8 Optional的詳細(xì)使用教程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Spring?Boot集成Milvus快速入門demo示例詳解

    Spring?Boot集成Milvus快速入門demo示例詳解

    Milvus是一種高性能向量數(shù)據(jù)庫,支持從筆記本到大型分布式系統(tǒng)的多環(huán)境運行,它以開源和云服務(wù)形式提供,是LFAI & Data Foundation的項目,采用Apache 2.0許可,Milvus特別支持高并行化和解耦的系統(tǒng)架構(gòu),使其能夠隨數(shù)據(jù)增長而擴展,支持各種復(fù)雜搜索功能,滿足企業(yè)級AI應(yīng)用需求
    2024-09-09
  • 關(guān)于yml文件字符串,List,Map的書寫方式并使用@ConfigurationProperties注入配置類

    關(guān)于yml文件字符串,List,Map的書寫方式并使用@ConfigurationProperties注入配置類

    這篇文章主要介紹了關(guān)于yml文件字符串,List,Map的書寫方式并使用@ConfigurationProperties注入配置類,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java設(shè)計模式的策略模式簡析

    Java設(shè)計模式的策略模式簡析

    這篇文章主要介紹了Java設(shè)計模式的策略模式簡析,策略模式中定義了一系列的算法族,算法族指的是類似于一系列的行為、策略,策略模式將一系列的行為封裝成類,既可以說是將每一種相類似的行為都封裝成一個類,也有可能存在特殊的不進行封裝的行為,需要的朋友可以參考下
    2023-12-12
  • Linux系統(tǒng)Docker拉取JDK21鏡像超細(xì)詳解

    Linux系統(tǒng)Docker拉取JDK21鏡像超細(xì)詳解

    這篇文章主要介紹了如何在Linux系統(tǒng)上使用Docker拉取JDK21鏡像,并基于該鏡像搭建開發(fā)和測試環(huán)境,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-12-12
  • Spring MVC接口防數(shù)據(jù)篡改和重復(fù)提交

    Spring MVC接口防數(shù)據(jù)篡改和重復(fù)提交

    這篇文章主要為大家詳細(xì)介紹了Spring MVC接口防數(shù)據(jù)篡改和重復(fù)提交,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評論

左权县| 苗栗市| 分宜县| 双鸭山市| 明星| 东阿县| 布拖县| 禄丰县| 池州市| 东乡县| 纳雍县| 琼中| 桑日县| 砚山县| 玉田县| 寻甸| 德令哈市| 米泉市| 茌平县| 霍山县| 明水县| 沛县| 夏河县| 自贡市| 颍上县| 略阳县| 望城县| 乳源| 临海市| 凤翔县| 南通市| 汶川县| 达尔| 宁国市| 盐津县| 吉木乃县| 天长市| 怀集县| 云龙县| 保定市| 辽阳市|