2012-10-19 27 views
5

là có thể trong Java để tạo tham chiếu yếu có đối tượng chỉ có thể được gửi tới bộ thu gom rác nếu điều kiện được chỉ định trả về true?Tham chiếu yếu với điều kiện/thời gian chờ

Hãy nói rằng tôi có một cái gì đó giống như một bộ nhớ cache mà bản đồ số ID để một số dữ liệu:

Map<Integer, SomeData> cache = new HashMap<>(); 

SomeData có hai phương pháp quan trọng - void updateTime(), mà chỉ đặt một biến nội bộ để thời gian hiện tại, và boolean canBeDeleted(), mà kiểm tra xem đối tượng có hoặc chưa được sử dụng trong 10 phút qua (chỉ đơn giản bằng cách so sánh thời gian hiện tại và thời gian đã lưu cộng với 10 phút). Nếu nó không được sử dụng trong khoảng thời gian nhất định này, phương thức trả về true và đối tượng có thể bị xóa khỏi bộ nhớ cache ...

Tuy nhiên, khi tạo bộ nhớ cache có tham chiếu yếu thay vì mạnh:

Map<Integer, WeakReference<SomeData>> cache = new HashMap<>(); 

Sau đó, chỉ điều WeakReference kiểm tra có lẽ là tài liệu tham khảo mạnh càng tốt để các đối tượng, nhưng tôi muốn nếu nó cũng kiểm tra tình trạng của tôi canBeDeleted() và không loại bỏ các tài liệu tham khảo nếu nó trở false. Có cách nào để làm điều này?

(Trên hết, có rò rỉ bộ nhớ và tôi không biết cách giải quyết nó ... Khi đối tượng bên trong WeakReference bị xóa, bản đồ vẫn chứa cặp khóa/giá trị không cần thiết).

Xin cảm ơn trước.

+0

Nếu bạn nhìn vào [ 'ổi caches'] (http://code.google.com/p/guava-libraries/wiki/CachesExplained), bạn có thể tạo một trong đó tự động xóa các mục không được tham chiếu trong một thời gian nhất định. – Keppil

+0

Đối với sự cố trong "()": bạn vẫn phải dọn dẹp bản đồ của mình. Việc xóa ứng dụng khách của WeakRef sẽ không tự động xóa mục nhập bản đồ. – Fildor

Trả lời

0

Bạn chỉ có thể xóa khóa trong bộ nhớ cache trong đó điều kiện là đúng.

+0

Tôi biết, nhưng sau đó tôi cần phải có một thread riêng biệt mà sẽ đi qua bộ nhớ cache ví dụ cứ 10 phút một lần và sẽ xóa tất cả mọi thứ không cần thiết.Nhưng tôi muốn tránh một sợi khác và để làm điều này với một số loại hợp tác với bộ thu gom rác, nếu có thể. –

+0

Nếu bạn muốn kiểm tra xem liệu điều kiện của bạn có trả về 'true' hay không, bạn sẽ cần phải đi qua bộ đệm ẩn. Nó là khá không rõ ràng những gì bạn muốn đạt được. –

2

Bạn có thể sử dụng LinkedHashMap#removeEldestEntry mặc dù nó không cung cấp cho bạn cách để loại bỏ dựa trên lượng thời gian vào bên trong Cache, nó cung cấp cho bạn một cách để loại bỏ các mục dựa trên việc nó được truy cập hay không.

Nó cung cấp cho người triển khai cơ hội loại bỏ mục nhập lớn nhất mỗi khi một mục mới được thêm vào. Điều này rất hữu ích nếu bản đồ đại diện cho bộ nhớ cache: nó cho phép bản đồ giảm mức tiêu thụ bộ nhớ bằng cách xóa các mục nhập cũ.

protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { 
    return size() > limit; 

Cũng nên nhớ bạn cần phải khởi tạo LinkedHashMap với accessOrdertrue.

accessOrder - chế độ đặt hàng - đúng cho thứ tự truy cập, sai cho thứ tự chèn.

Vì vậy, đặt nó tất cả các nguồn cùng nên như dưới đây

public class Cache<K, V> extends LinkedHashMap<K, V> { 
    private final int MAX_ENTRIES = 100; 
    public Cache() { 
     super(16, 0.75f, true);// accessOrder is true 
    } 
    @Override 
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { 
     return size() > MAX_ENTRIES; 
    } 
} 
Các vấn đề liên quan