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

java仿C++模擬實(shí)現(xiàn)一個智能指針

 更新時間:2025年05月30日 09:23:15   作者:Katie。  
在?C++?等語言中,指針?是對內(nèi)存地址的直接操作,為靈活管理內(nèi)存和實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)提供了強(qiáng)大能力,本文將使用純Java實(shí)現(xiàn)一個通用的?SmartPointer<T>框架為各種資源類型提供類似?C++?智能指針的使用體驗

一、項目背景詳細(xì)介紹

1. 指針與智能指針概述

在 C++ 等語言中,指針 是對內(nèi)存地址的直接操作,為靈活管理內(nèi)存和實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)提供了強(qiáng)大能力,但也帶來懸掛指針、內(nèi)存泄漏和雙重釋放等安全風(fēng)險。為此,C++11 標(biāo)準(zhǔn)引入了 智能指針(smart pointer),如 std::unique_ptr、std::shared_ptr 和 std::weak_ptr,在構(gòu)造和析構(gòu)時自動管理資源,避免手動 delete 帶來的諸多問題。

Java 語言本身運(yùn)行在垃圾回收(GC)機(jī)制下,所有對象均由 JVM 自動回收,程序員無需顯式釋放內(nèi)存。但在以下場景中,仍需要“智能指針”式的自動化資源管理:

非內(nèi)存資源:如文件句柄、數(shù)據(jù)庫連接、網(wǎng)絡(luò)套接字,這些資源不由 GC 管理,需要顯式關(guān)閉。

引用計數(shù):在復(fù)雜對象圖中,有時需要統(tǒng)計引用或在最后一個引用消亡時觸發(fā)某些清理動作。

弱引用管理:實(shí)現(xiàn)緩存或監(jiān)聽器時希望對象可被 GC 回收。

本項目旨在使用純 Java 實(shí)現(xiàn)一個通用的 SmartPointer<T> 框架,通過引用計數(shù)或自動關(guān)閉語義,為各種資源類型提供類似 C++ 智能指針的使用體驗。

1.2 智能指針在 Java 中的必要性

自動管理非內(nèi)存資源:避免因忘記關(guān)閉流或連接導(dǎo)致的資源泄漏;

延遲清理邏輯:可在最后一個引用消亡時執(zhí)行自定義回調(diào);

緩存與弱引用:結(jié)合 WeakReference 與 ReferenceQueue 實(shí)現(xiàn)自動過期緩存;

統(tǒng)一 API:對外暴露與普通對象相同接口,增強(qiáng)代碼可讀性與安全性。

二、項目需求詳細(xì)介紹

1.核心接口

定義泛型接口 SmartPointer<T>:

public interface SmartPointer<T> {
    T get();                    // 獲取底層對象
    void retain();             // 增加引用計數(shù)
    void release();            // 減少引用計數(shù),必要時觸發(fā)清理
    int useCount();            // 當(dāng)前引用計數(shù)
    boolean isValid();         // 底層資源是否仍可用
}

2.實(shí)現(xiàn)類

RefCountedPointer<T>:基于引用計數(shù)(AtomicInteger)管理對象,最后一個 release() 時執(zhí)行可選的清理函數(shù)。

AutoClosePointer<T extends AutoCloseable>:包裝 AutoCloseable 類型,在引用計數(shù)為零時自動調(diào)用 close();

3.弱引用支持

WeakSmartPointer<T>:內(nèi)部用 WeakReference<T> 和 ReferenceQueue<T>,對象回收時觸發(fā)清理回調(diào);

4.線程安全

所有實(shí)現(xiàn)均使用原子操作或同步保證多線程環(huán)境下的正確引用計數(shù)。

5.使用示例

文件流、數(shù)據(jù)庫連接、線程執(zhí)行上下文等多種場景示例。

6.擴(kuò)展性

支持自定義清理動作(Runnable onFinalize);

可組合多種智能指針。

7.測試與示例

單元測試驗證 retain/release 語義、并發(fā)安全、弱引用回調(diào);

示例 main 演示文件讀取、緩存管理。

8.文檔與注釋

Javadoc 注釋所有接口與方法;

README 說明使用方法與注意事項。

9.教學(xué)要求

在博客中結(jié)合 UML 類圖和時序圖解釋引用計數(shù)和弱引用回收機(jī)制;

詳細(xì)討論與 GC、LeakSafe、try-with-resources 的區(qū)別。

三、相關(guān)技術(shù)詳細(xì)介紹

3.1 Java 垃圾回收與 AutoCloseable

JVM 會在無強(qiáng)引用對象時自動回收內(nèi)存,但不管理文件句柄、數(shù)據(jù)庫連接等非內(nèi)存資源,需實(shí)現(xiàn) AutoCloseable 并在 close() 中釋放資源。

Java 7 引入了 try-with-resources 語法糖,但僅對局部作用域資源生效,不能在任意作用域通過引用計數(shù)自動關(guān)閉。

3.2 引用計數(shù)

維護(hù)一個 AtomicInteger count;

retain() 時 count.incrementAndGet();

release() 時 count.decrementAndGet(),當(dāng)返回 0 時執(zhí)行清理;

需防止循環(huán)引用或多次釋放。

3.3 弱引用與 ReferenceQueue

WeakReference<T>:不會阻止對象被回收,對象回收后弱引用入隊;

ReferenceQueue<T>:持有弱引用的引用隊列,可在后臺線程中監(jiān)聽并執(zhí)行回調(diào);

適合緩存場景:對象被卸載后自動從緩存中移除。

3.4 線程安全與并發(fā)測試

使用 AtomicInteger 和 volatile,或在必要處進(jìn)行 synchronized;

單元測試中模擬高并發(fā) retain/release 調(diào)用,驗證計數(shù)準(zhǔn)確與僅調(diào)用一次清理。

四、實(shí)現(xiàn)思路詳細(xì)介紹

1.SmartPointer<T> 接口

定義基礎(chǔ)方法,屏蔽底層實(shí)現(xiàn);

2.AbstractRefCountedPointer<T>

抽象基類,維護(hù) protected final T referent; private final AtomicInteger refCount = new AtomicInteger(1); private final Runnable cleanup;

實(shí)現(xiàn) retain(), useCount(), isValid();

release() 調(diào)用 if (refCount.decrementAndGet()==0) cleanup.run();

3.RefCountedPointer<T>

繼承自 AbstractRefCountedPointer<T>,提供構(gòu)造器接受 referent 和可選 cleanup;

4.AutoClosePointer<T extends AutoCloseable>

構(gòu)造時傳入 T referent,cleanup = referent::close;

5.WeakSmartPointer<T>

內(nèi)部持有 WeakReference<T> weakRef 和 ReferenceQueue<T> queue;

單例后臺線程監(jiān)聽 queue,取出已回收對象對應(yīng)弱引用并執(zhí)行回調(diào);

6.使用示例

文件讀取:用 AutoClosePointer<InputStream> 自動 close();

連接池:用 RefCountedPointer<Connection> 多處 retain,最后自動 shutdown;

緩存:WeakSmartPointer<LargeObject>,對象回收時自動從 Map 中移除。

7.線程安全

refCount 用原子操作保證;弱引用隊列監(jiān)聽使用單線程安全;

8.測試

JUnit 測試 refCount 邊界、并發(fā)、多次 release() 無錯誤;

弱引用回收后回調(diào)執(zhí)行一次。

五、完整實(shí)現(xiàn)代碼

// =================================================================
// 文件:SmartPointer.java
// 包名:com.example.smartptr
// 功能:通用智能指針接口
// =================================================================
package com.example.smartptr;
 
public interface SmartPointer<T> {
    /** 返回被管理的對象,若已清理則拋異常 */
    T get();
    /** 增加引用計數(shù) */
    void retain();
    /** 減少引用計數(shù),必要時觸發(fā)清理 */
    void release();
    /** 當(dāng)前引用計數(shù) */
    int useCount();
    /** 對象是否仍未被清理 */
    boolean isValid();
}
 
// =================================================================
// 文件:AbstractRefCountedPointer.java
// 包名:com.example.smartptr
// 功能:帶引用計數(shù)與清理回調(diào)的抽象基類
// =================================================================
package com.example.smartptr;
 
import java.util.concurrent.atomic.AtomicInteger;
 
public abstract class AbstractRefCountedPointer<T> implements SmartPointer<T> {
    protected final T referent;
    private final AtomicInteger refCount = new AtomicInteger(1);
    private final Runnable cleanup;
    private volatile boolean valid = true;
 
    protected AbstractRefCountedPointer(T referent, Runnable cleanup) {
        if (referent == null) throw new IllegalArgumentException("Referent cannot be null");
        this.referent = referent;
        this.cleanup  = cleanup;
    }
 
    @Override
    public T get() {
        if (!valid) throw new IllegalStateException("Resource already released");
        return referent;
    }
 
    @Override
    public void retain() {
        if (!valid) throw new IllegalStateException("Cannot retain released resource");
        refCount.incrementAndGet();
    }
 
    @Override
    public void release() {
        int rc = refCount.decrementAndGet();
        if (rc < 0) throw new IllegalStateException("release() called too many times");
        if (rc == 0) {
            valid = false;
            cleanup.run();
        }
    }
 
    @Override
    public int useCount() {
        return refCount.get();
    }
 
    @Override
    public boolean isValid() {
        return valid;
    }
}
 
// =================================================================
// 文件:RefCountedPointer.java
// 包名:com.example.smartptr
// 功能:普通對象的引用計數(shù)智能指針
// =================================================================
package com.example.smartptr;
 
public class RefCountedPointer<T> extends AbstractRefCountedPointer<T> {
    public RefCountedPointer(T referent, Runnable cleanup) {
        super(referent, cleanup != null ? cleanup : () -> {});
    }
    public RefCountedPointer(T referent) {
        this(referent, () -> {});
    }
}
 
// =================================================================
// 文件:AutoClosePointer.java
// 包名:com.example.smartptr
// 功能:自動關(guān)閉 AutoCloseable 資源的智能指針
// =================================================================
package com.example.smartptr;
 
public class AutoClosePointer<T extends AutoCloseable>
        extends AbstractRefCountedPointer<T> {
    public AutoClosePointer(T referent) {
        super(referent, () -> {
            try { referent.close(); }
            catch (Exception e) { /* 可記錄日志 */ }
        });
    }
}
 
// =================================================================
// 文件:WeakSmartPointer.java
// 包名:com.example.smartptr
// 功能:弱引用智能指針,資源被 GC 回收時觸發(fā)回調(diào)
// =================================================================
package com.example.smartptr;
 
import java.lang.ref.*;
import java.util.concurrent.*;
 
public class WeakSmartPointer<T> implements SmartPointer<T> {
    private final WeakReference<T> weakRef;
    private final ReferenceQueue<T> queue = new ReferenceQueue<>();
    private final Runnable cleanup;
    private volatile boolean valid = true;
 
    public WeakSmartPointer(T referent, Runnable cleanup) {
        this.weakRef = new WeakReference<>(referent, queue);
        this.cleanup = cleanup != null ? cleanup : () -> {};
        startWatcher();
    }
 
    private void startWatcher() {
        Thread watcher = new Thread(() -> {
            try {
                Reference<? extends T> r = queue.remove();
                if (r == weakRef) {
                    valid = false;
                    cleanup.run();
                }
            } catch (InterruptedException ignored) {}
        }, "WeakPtr-Watcher");
        watcher.setDaemon(true);
        watcher.start();
    }
 
    @Override
    public T get() {
        T t = weakRef.get();
        if (t == null) throw new IllegalStateException("Resource already GCed");
        return t;
    }
 
    @Override
    public void retain() {
        throw new UnsupportedOperationException("WeakSmartPointer does not support retain()");
    }
 
    @Override
    public void release() {
        throw new UnsupportedOperationException("WeakSmartPointer does not support release()");
    }
 
    @Override
    public int useCount() {
        return valid && weakRef.get() != null ? 1 : 0;
    }
 
    @Override
    public boolean isValid() {
        return valid && weakRef.get() != null;
    }
}
 
// =================================================================
// 文件:Main.java
// 包名:com.example.smartptr
// 功能:示例演示各種智能指針的使用場景
// =================================================================
package com.example.smartptr;
 
import java.io.*;
 
public class Main {
    public static void main(String[] args) throws Exception {
        System.out.println("=== RefCountedPointer 示例 ===");
        RefCountedPointer<StringBuilder> p = new RefCountedPointer<>(
            new StringBuilder("Hello"), () -> System.out.println("Cleanup called"));
        System.out.println("useCount=" + p.useCount());
        p.retain();
        System.out.println("useCount after retain=" + p.useCount());
        p.release();
        System.out.println("useCount after release=" + p.useCount());
        p.release(); // 最后一次,觸發(fā) cleanup
        System.out.println("isValid=" + p.isValid());
 
        System.out.println("\n=== AutoClosePointer 示例 ===");
        AutoClosePointer<FileInputStream> ap =
            new AutoClosePointer<>(new FileInputStream("test.txt"));
        FileInputStream fis = ap.get();
        System.out.println("File opened? " + (fis != null));
        ap.release(); // 自動 close()
 
        System.out.println("\n=== WeakSmartPointer 示例 ===");
        Object obj = new Object();
        WeakSmartPointer<Object> wp = new WeakSmartPointer<>(obj,
            () -> System.out.println("Weak cleanup called"));
        System.out.println("isValid before GC=" + wp.isValid());
        obj = null;
        System.gc(); Thread.sleep(100);
        System.out.println("isValid after GC=" + wp.isValid());
    }
}

六、代碼詳細(xì)解讀

SmartPointer<T>:統(tǒng)一接口;

AbstractRefCountedPointer<T>:引用計數(shù)基類,用 AtomicInteger 管理計數(shù),并在計數(shù)歸零時執(zhí)行清理回調(diào);

RefCountedPointer<T>:一般對象版,可選傳入自定義 cleanup;

AutoClosePointer<T>:針對 AutoCloseable,在最后一次 release() 時自動 close();

WeakSmartPointer<T>:使用 WeakReference 與后臺 ReferenceQueue 監(jiān)聽對象回收并執(zhí)行 cleanup;

七、項目詳細(xì)總結(jié)

本文在 Java 中手寫實(shí)現(xiàn)了多種“智能指針”模型:

引用計數(shù)智能指針:多處 retain/release,引用歸零時回調(diào);

自動關(guān)閉智能指針:封裝 AutoCloseable,最后釋放時自動關(guān)閉資源;

弱引用智能指針:結(jié)合 WeakReference 與 ReferenceQueue,對象 GC 后執(zhí)行回調(diào);

這些工具框架能幫助你在 Java 中對非內(nèi)存資源或需要特殊回調(diào)的對象進(jìn)行自動化管理,提升代碼安全性與健壯性。

八、項目常見問題及解答

Q1:Java 已有 GC,為什么還要引用計數(shù)?

A1:GC 只管理內(nèi)存,不負(fù)責(zé)文件、連接等資源,引用計數(shù)智能指針可在最后一個引用釋放時自動清理這些資源。

Q2:ReferenceQueue 會阻塞嗎?

A2:queue.remove() 會阻塞直到有引用入隊,因此 watcher 線程設(shè)置為守護(hù)線程并僅在一條引用回收時喚醒。

Q3:如何防止循環(huán)引用導(dǎo)致資源永不釋放?

A3:引用計數(shù)本身無法打破循環(huán)引用,可結(jié)合弱引用或手動調(diào)用 release() 斷開循環(huán)。

Q4:AutoClosePointer vs try-with-resources?

A4:try-with-resources 只在局部作用域有效,智能指針可跨作用域管理資源并延遲關(guān)閉。

Q5:使用智能指針會帶來性能開銷嗎?

A5:引用計數(shù)和弱引用機(jī)制有一定原子操作和線程管理開銷,應(yīng)在性能敏感場景做測評。

九、擴(kuò)展方向與性能優(yōu)化

循環(huán)引用檢測:結(jié)合 ReferenceQueue 和弱引用斷環(huán),避免循環(huán)引用泄漏;

異步清理:將 cleanup 回調(diào)提交線程池執(zhí)行,避免阻塞釋放線程;

自定義清理策略:支持不同場景的 retry、超時或降級處理;

分布式引用計數(shù):在分布式對象緩存中實(shí)現(xiàn)全局引用計數(shù);

與 Spring 集成:將智能指針作為 Bean 管理,利用容器生命周期自動管理資源。

到此這篇關(guān)于java仿C++模擬實(shí)現(xiàn)一個智能指針的文章就介紹到這了,更多相關(guān)java智能指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring中配置數(shù)據(jù)源的幾種方式

    Spring中配置數(shù)據(jù)源的幾種方式

    今天小編就為大家分享一篇關(guān)于Spring中配置數(shù)據(jù)源的幾種方式,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 詳解如何使用Spring的@FeignClient注解實(shí)現(xiàn)通信功能

    詳解如何使用Spring的@FeignClient注解實(shí)現(xiàn)通信功能

    SpringBoot是一個非常流行的Java框架,它提供了一系列工具來使這種交互無縫且高效,在這些工具中,@FeignClient注解因其易用性和強(qiáng)大的功能而脫穎而出, 在這篇文章中,我們將探討如何使用Spring的@FeignClient注解進(jìn)行客戶端-服務(wù)器通信,需要的朋友可以參考下
    2023-11-11
  • 淺談Spring5 響應(yīng)式編程

    淺談Spring5 響應(yīng)式編程

    本篇文章主要介紹了淺談Spring5 響應(yīng)式編程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • 使用IDEA開發(fā)配置Java Web的初始化過程

    使用IDEA開發(fā)配置Java Web的初始化過程

    該教程使用idea開發(fā)工具初始化javaweb項目,該運(yùn)行在tomcat服務(wù)器上通過配置項目環(huán)境變量保證tomcat正常啟動,具體操作配置教程參考下本文
    2021-06-06
  • shiro整合springmvc配置靜態(tài)資源過濾方式

    shiro整合springmvc配置靜態(tài)資源過濾方式

    文章介紹了在Spring Boot + Spring MVC + Shiro + JSP項目中,如何正確配置靜態(tài)資源路徑以避免在引入Shiro過濾器后資源加載失敗的問題
    2026-03-03
  • Spring Boot jpa Service層代碼實(shí)例

    Spring Boot jpa Service層代碼實(shí)例

    這篇文章主要介紹了Spring Boot jpa Service層代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • 從Myeclipse 導(dǎo)入到eclipse中無法識別為 web項目 問題的解決步驟

    從Myeclipse 導(dǎo)入到eclipse中無法識別為 web項目 問題的解決步驟

    這篇文章主要介紹了從Myeclipse 導(dǎo)入到eclipse中無法識別為 web項目 問題的解決步驟,需要的朋友可以參考下
    2018-05-05
  • 詳解Mybatis是如何解析配置文件的

    詳解Mybatis是如何解析配置文件的

    這篇文章主要介紹了詳解Mybatis是如何解析配置文件的,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • SpringBoot actuator 健康檢查不通過的解決方案

    SpringBoot actuator 健康檢查不通過的解決方案

    這篇文章主要介紹了SpringBoot actuator 健康檢查不通過的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • SpringBoot實(shí)現(xiàn)簡單的日志鏈路追蹤

    SpringBoot實(shí)現(xiàn)簡單的日志鏈路追蹤

    隨著分布式應(yīng)用的普及,現(xiàn)在的一些應(yīng)用系統(tǒng)不再像以前,所有的文件(前后端程序)都打包在一個包中,本文通過一個簡單的SpringBoot應(yīng)用來總結(jié),我們?nèi)绾螌⑷罩敬?lián)起來,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-10-10

最新評論

班戈县| 兴城市| 楚雄市| 蓝山县| 新津县| 浠水县| 仙桃市| 修水县| 唐山市| 淳化县| 隆回县| 金湖县| 台中县| 金堂县| 新竹县| 衡山县| 澳门| 永登县| 高陵县| 界首市| 南投市| 涡阳县| 桐柏县| 神池县| 平阴县| 巧家县| 曲阳县| 富顺县| 黄龙县| 和平区| 宁远县| 遵义县| 东乡族自治县| 巨鹿县| 肥城市| 武山县| 芮城县| 秦皇岛市| 岗巴县| 陆良县| 绵竹市|