Tìm kiếm bộ nhớ đệm trong bộ nhớ Java đơn giản [đã đóng]


102

Tôi đang tìm kiếm một bộ nhớ đệm trong bộ nhớ Java đơn giản có khả năng đồng thời tốt (vì vậy LinkedHashMap không đủ tốt) và có thể được tuần tự hóa vào đĩa định kỳ.

Một tính năng tôi cần, nhưng đã được chứng minh là khó tìm, là một cách để "nhìn trộm" một đối tượng. Bằng cách này, ý tôi là lấy một đối tượng từ bộ nhớ cache mà không làm cho bộ nhớ cache giữ đối tượng lâu hơn nó sẽ có.

Cập nhật: Một yêu cầu bổ sung mà tôi đã quên đề cập là tôi cần có thể sửa đổi các đối tượng được lưu trong bộ nhớ cache (chúng chứa mảng float) tại chỗ.

Bất cứ ai có thể cung cấp bất kỳ khuyến nghị?


1
Tôi đang tìm kiếm thứ gì đó tương tự "trong quá trình" và trọng lượng nhẹ hơn. Tôi muốn sử dụng nó để lưu trữ một số dữ liệu trong một plugin Eclipse trong heap. Ehcache và JCS có vẻ quá nặng / phân phối / J2EE đối với sở thích của tôi.
Uri 22/02/09

1
có thể trùng lặp của Lightweight Java Object Cache API
Raedwald

Tôi sẽ giới thiệu Apache Ignite ( firete.apache.org )
Bhagat S.

1
Rằng câu hỏi này đã khép lại (6 năm sau sự thật) và nó vẫn là điều mà mọi người đang thắc mắc ngày nay, cho thấy hệ thống điều hành của SO đang thất bại như thế nào.
dustinevan

Câu trả lời:


61

Vì câu hỏi này ban đầu được hỏi, thư viện Guava của Google hiện bao gồm một bộ nhớ cache mạnh mẽ và linh hoạt. Tôi muốn khuyên bạn nên sử dụng cái này.


3
Xin lưu ý rằng Spring không hỗ trợ bộ nhớ cache trong Guava nữa: stackoverflow.com/questions/44175085/…
sinner

@sanity có triển khai Jcache không?
gaurav

Caffine cũng là một thư viện bộ nhớ đệm tốt và hiệu quả. Caffeine là một thư viện bộ nhớ đệm hiệu suất cao, gần tối ưu dựa trên Java 8. Caffeine cung cấp một bộ nhớ đệm trong bộ nhớ bằng cách sử dụng API lấy cảm hứng từ Google Guava
Slavus

37

Ehcache là một giải pháp khá tốt cho việc này và có một cách để xem trộm ( getQuiet () là phương thức) để nó không cập nhật dấu thời gian nhàn rỗi. Trong nội bộ, Ehcache được triển khai với một tập hợp các bản đồ, giống như ConcurrentHashMap, vì vậy nó có các loại lợi ích tương tự.


2
Cảm ơn, một câu hỏi bổ sung: Nếu tôi truy xuất một đối tượng từ EHcache (ví dụ, một mảng) và sửa đổi nó - đối tượng có được cập nhật trong bộ đệm không? I E. EHCache có duy trì các tham chiếu đến các đối tượng không?
sanity

1
Tôi tin như vậy nhưng để làm điều này một cách an toàn, tất nhiên bạn phải khóa đối tượng một cách thích hợp.
Alex Miller

Tôi yêu ehcache, tuy nhiên, nó là một cái lọ 10mb. Đường rất rộng.
markthegrea

23

Nếu bạn cần một cái gì đó đơn giản, cái này có phù hợp với hóa đơn không?

Map<K, V> myCache = Collections.synchronizedMap(new WeakHashMap<K, V>());

Nó sẽ không lưu vào đĩa, nhưng bạn đã nói rằng bạn muốn đơn giản ...

Liên kết:

(Như Adam đã nhận xét, việc đồng bộ hóa bản đồ có tác dụng về mặt hiệu suất. Không nói rằng ý tưởng này không có cơ sở, nhưng cũng đủ coi là một giải pháp nhanh chóng và bẩn thỉu.)


4
Đồng bộ hóa toàn bộ bản đồ khổng lồ là một hình phạt nặng nề. Bạn có thể dễ dàng lưu trữ các loại yếu trong một bản đồ băm đồng thời và loại bỏ chúng theo định kỳ.
Adam Gent

7
ConcurrentHashMap là tốt hơn so với Collections.synchronizedMap stackoverflow.com/questions/6692008/...
Pablo Moretti

8
Về mặt hiệu suất, ConcurrentHashMap hoàn toàn hoạt động tốt hơn, nhưng nó không chia sẻ các thuộc tính của WeakHashMap liên quan đến việc cho phép bộ thu gom rác lấy lại bộ nhớ. Điều này có thể có hoặc không quan trọng đối với bạn.
Evan

4
Sau đó sử dụng ConcurrentHashMap<WeakReference<T>>. docs.oracle.com/javase/7/docs/api/java/lang/ref/…
jdmichal

19

Một tùy chọn khác cho bộ đệm java trong bộ nhớ là cache2k . Hiệu suất trong bộ nhớ vượt trội so với EHCache và google ổi, hãy xem trang điểm chuẩn cache2k .

Cách sử dụng tương tự như các bộ nhớ đệm khác. Đây là một ví dụ:

Cache<String,String> cache = new Cache2kBuilder<String, String>() {}
  .expireAfterWrite(5, TimeUnit.MINUTES)    // expire/refresh after 5 minutes
  .resilienceDuration(30, TimeUnit.SECONDS) // cope with at most 30 seconds
                                          // outage before propagating 
                                          // exceptions
  .refreshAhead(true)                       // keep fresh when expiring
  .loader(new CacheLoader<String, String>() {
    @Override
    public String load(final String key) throws Exception {
      return ....;
    }
  })
  .build();
String val = cache.peek("something");
cache.put("something", "hello");
val = cache.get("something");

Nếu bạn có google ổi là phụ thuộc thì hãy thử bộ nhớ cache của ổi, có thể là một giải pháp thay thế tốt.


cruftex, nếu tôi đóng ứng dụng của mình, bộ đệm sẽ phá hủy tất cả dữ liệu đã đăng ký hay không?
Menai Ala Eddine - Aladdin

10

Bạn có thể dễ dàng sử dụng imcache . Dưới đây là một mã mẫu.

void example(){
    Cache<Integer,Integer> cache = CacheBuilder.heapCache().
    cacheLoader(new CacheLoader<Integer, Integer>() {
        public Integer load(Integer key) {
            return null;
        }
    }).capacity(10000).build(); 
}

9

Thử cái này:

import java.util.*;

public class SimpleCacheManager {

    private static SimpleCacheManager instance;
    private static Object monitor = new Object();
    private Map<String, Object> cache = Collections.synchronizedMap(new HashMap<String, Object>());

    private SimpleCacheManager() {
    }

    public void put(String cacheKey, Object value) {
        cache.put(cacheKey, value);
    }

    public Object get(String cacheKey) {
        return cache.get(cacheKey);
    }

    public void clear(String cacheKey) {
        cache.put(cacheKey, null);
    }

    public void clear() {
        cache.clear();
    }

    public static SimpleCacheManager getInstance() {
        if (instance == null) {
            synchronized (monitor) {
                if (instance == null) {
                    instance = new SimpleCacheManager();
                }
            }
        }
        return instance;
    }

}

Các vấn đề với việc dựa vào một bản đồ đồng bộ đã được thảo luận trong các câu trả lời khác.
sanity

@sergeyB: Tôi đang tìm kiếm một giải pháp tương tự mà rất đơn giản để thực hiện bộ nhớ cache ... Cảm ơn
Prakruti Pathik

1
public static SimpleCacheManager getInstance() {Nên public synchronized static SimpleCacheManager getInstance() {nếu không thì if (instance == null) {không phải là thread an toàn. Trong trường hợp đó, bạn có thể xóa tất cả đối tượng màn hình cùng nhau vì quá trình đồng bộ hóa diễn ra cho tất cả các lệnh gọi getInstance (), hãy xem: javaworld.com/article/2073352/core-java/…
Can Kavaklğo 15lu

Tôi có thể khuyên bạn nên sử dụng enum cho singleton không? dzone.com/articles/java-singletons-using-enum
Erk



0

Dùng thử Ehcache ? Nó cho phép bạn cài đặt các thuật toán hết hạn trong bộ nhớ đệm của riêng mình để bạn có thể kiểm soát chức năng xem trước của mình.

Bạn có thể tuần tự hóa vào đĩa, cơ sở dữ liệu, trên một cụm, v.v.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.