簡體   English   中英

跟蹤Java中的引用

[英]Keeping track of references in Java

在Java中,是否有任何方法可以判斷是否正在其他線程中(或通常在線程中)維護對對象的引用?

考慮以下類別:

public class ResourcePool<TYPE>
{
    private final Queue<Object> emptyLocks = new LinkedBlockingQueue<>();

    private final Queue<TYPE> available = new LinkedBlockingQueue<>();
    private final Queue<TYPE> claimed = new LinkedBlockingQueue<>();

    public void add(TYPE resource)
    {
        available.add(resource);
    }

    public TYPE claim() throws InterruptedException
    {
        if (available.isEmpty())
        {
            Object lock = new Object();
            synchronized (lock)
            {
                emptyLocks.add(lock);
                lock.wait();
            }
        }

        TYPE resource = available.poll();
        claimed.add(resource);
        return resource;
    }

    public void release(TYPE resource)
    {
        if (!claimed.remove(resource)) return;
        available.add(resource);

        Object lock = emptyLocks.poll();
        if (lock != null) synchronized (lock) {lock.notify();}
    }
}

這里的想法是,多個線程可以聲明/釋放資源,以使兩個線程在任何給定時刻永遠不能擁有同一資源。 但是,如果線程忘記釋放資源,會發生什么? 更糟糕的是,如果線程調用release()然后繼續處理資源,該怎么辦?

使用WeakReference類,可以判斷何時不再存在對給定對象的強引用。 但是,發生這種情況時,該對象將被垃圾回收,並且不見了。 SoftReference可能會起作用,但是在將資源重新放入“可用”列表之前,仍有機會對我們的資源進行GC處理。

因此,這里的問題有沒有辦法跟蹤這些資源是否仍在實際使用中?

理想情況下,線程可以聲明()資源,並在需要時使用它們,並且一旦不再維護引用,這些資源將自動釋放。 我認為這將非常優雅,並且在其他情況下也很有用。

答案很簡單:否

GC在VM全局級別工作,並且在當前實施中(至少在Hotspot中),它不使用引用計數,更不用說引用跟蹤。 這意味着即使VM也不總是知道任意時間點所引用的內容。

通常,GC還是錯誤的工具,無法跟蹤需要及時發布的內容。 GC可能很少運行(在極端情況下,GC可能會調整為每隔幾個小時運行一次)。 您可能希望自己的資源在擁有塊作用域結束后立即可用於其他線程。 這個要求與GC處理不嚴的要求大不相同。

您想要的是立即檢測每個線程超出范圍的情況。 雖然這是一個不錯的功能,但問題是,這樣做是否值得付出代價的性能影響。

資源的示例以及在釋放后釋放/保留資源的線程“遺忘”的情況可以按照慣例處理:使用try-finally或濫用try-with-resources塊以確保生命周期是正確維護。

為了捕獲資源的意外泄漏,您可以濫用finalize; 但是, 資源完成 ,它也不是可預測的(而且您只能進行清理,不應完成資源的復活;有關完成此操作,請參見JLS)。

編輯:您可以輕松地抵御利用資源釋放 stroing在資源所有者胭脂線程。 然后,資源可以執行運行時檢查,以確保調用線程確實是當前所有者。

您正在搜索finalize()方法。 當無法再訪問對象時,必須重寫此方法以進行清理。

請注意 ,創建finalize()方法並不像看起來那樣簡單(如這些答案所述 )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM