Mencari cache dalam memori Java yang sederhana [ditutup]


102

Saya mencari cache dalam memori Java sederhana yang memiliki konkurensi yang baik (jadi LinkedHashMap tidak cukup baik), dan yang dapat diserialkan ke disk secara berkala.

Satu fitur yang saya butuhkan, tetapi yang terbukti sulit ditemukan, adalah cara untuk "mengintip" suatu objek. Maksud saya, mengambil objek dari cache tanpa menyebabkan cache menahan objek lebih lama dari yang seharusnya.

Pembaruan: Persyaratan tambahan yang tidak saya sebutkan adalah bahwa saya harus dapat memodifikasi objek yang di-cache (berisi array mengambang) di tempat.

Adakah yang bisa memberikan rekomendasi?


1
Saya mencari sesuatu yang serupa yaitu "dalam proses" dan bobot yang lebih ringan. Saya ingin menggunakannya untuk menyimpan beberapa data dalam plugin Eclipse di heap. Ehcache dan JCS sepertinya terlalu kelas berat / didistribusikan / J2EE untuk selera saya.
Uri

1
kemungkinan duplikat API cache Objek Java Ringan
Raedwald

Saya akan merekomendasikan Apache Ignite ( ignite.apache.org )
Bhagat S.

1
Bahwa pertanyaan ini sudah ditutup (6 tahun setelah kejadian) dan masih menjadi pertanyaan orang hari ini, menunjukkan bagaimana sistem moderator SO gagal.
dustinevan

Jawaban:


61

Karena pertanyaan ini awalnya ditanyakan, pustaka Guava Google sekarang menyertakan cache yang kuat dan fleksibel. Saya akan merekomendasikan menggunakan ini.


3
Harap dicatat bahwa Spring tidak lagi mendukung cache Guava: stackoverflow.com/questions/44175085/…
sinner

@ sanity apakah itu mengimplementasikan Jcache?
Gaurav

Caffine juga bagus dan perpustakaan cache yang bagus. Kafein adalah kinerja tinggi, perpustakaan caching yang hampir optimal berdasarkan Java 8. Kafein menyediakan cache dalam memori menggunakan API yang terinspirasi Google Guava
Slavus

37

Ehcache adalah solusi yang cukup bagus untuk ini dan memiliki cara untuk mengintip ( getQuiet () adalah metode) sedemikian rupa sehingga tidak memperbarui stempel waktu idle. Secara internal, Ehcache diimplementasikan dengan sekumpulan peta, seperti ConcurrentHashMap, sehingga memiliki jenis manfaat konkurensi yang serupa.


2
Terima kasih, pertanyaan tambahan: Jika saya mengambil sebuah objek dari EHcache (katakanlah, sebuah array), dan memodifikasinya - akankah objek tersebut diperbarui dalam cache? yaitu. apakah EHCache mempertahankan referensi ke objek?
kewarasan

1
Saya yakin begitu, tetapi untuk melakukan ini dengan aman, Anda harus mengunci objek dengan tepat, tentu saja.
Alex Miller

Saya suka ehcache, bagaimanapun, ini adalah toples 10mb. Terlalu besar.
markthegrea

23

Jika Anda membutuhkan sesuatu yang sederhana, apakah ini sesuai dengan tagihan?

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

Ini tidak akan disimpan ke disk, tetapi Anda bilang ingin sederhana ...

Tautan:

(Seperti yang dikomentari Adam, menyinkronkan peta memiliki kinerja yang baik. Tidak mengatakan bahwa gagasan itu tidak memiliki masalah, tetapi akan cukup sebagai solusi cepat dan kotor.)


4
Menyinkronkan seluruh peta raksasa adalah hukuman yang berat. Anda dapat dengan mudah menyimpan tipe lemah dalam peta hash bersamaan dan menghapusnya secara berkala.
Adam Gent

7
ConcurrentHashMap lebih baik daripada Collections.synchronizedMap stackoverflow.com/questions/6692008/…
Pablo Moretti

8
Dari segi kinerja, ConcurrentHashMap benar-benar berkinerja lebih baik, tetapi tidak berbagi properti WeakHashMap sehubungan dengan mengizinkan pengumpul sampah untuk merebut kembali memori. Ini mungkin penting atau tidak penting bagi Anda.
Evan

4
Kemudian gunakan ConcurrentHashMap<WeakReference<T>>. docs.oracle.com/javase/7/docs/api/java/lang/ref/…
jdmichal

19

Pilihan lain untuk cache java dalam memori adalah cache2k . Kinerja dalam memori lebih unggul dari EHCache dan google guava, lihat halaman benchmark cache2k .

Pola penggunaannya mirip dengan cache lainnya. Berikut ini contohnya:

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");

Jika Anda memiliki google guava sebagai ketergantungan maka mencoba cache jambu biji, mungkin bisa menjadi alternatif yang baik.


cruftex, jika saya menutup aplikasi saya, cache akan menghancurkan semua data yang terdaftar atau tidak?
Menai Ala Eddine - Aladdin

10

Anda dapat dengan mudah menggunakan imcache . Kode contoh ada di bawah.

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

9

Coba ini:

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;
    }

}

Masalah dengan mengandalkan peta tersinkronisasi sudah dibahas di jawaban lain.
kewarasan

@sergeyB: Saya sedang mencari solusi serupa yang sederhana untuk mengimplementasikan cache ... Terima kasih
Prakruti Pathik

1
public static SimpleCacheManager getInstance() {harus public synchronized static SimpleCacheManager getInstance() {sebaliknya if (instance == null) {tidak benang aman. Dalam hal ini Anda dapat menghapus objek monitor secara bersamaan karena sinkronisasi berlangsung untuk semua panggilan getInstance (), lihat: javaworld.com/article/2073352/core-java/…
Can Kavaklıoğlu

Bolehkah saya merekomendasikan menggunakan enum untuk singleton? dzone.com/articles/java-singletons-using-enum
Erk



0

Coba Ehcache ? Ini memungkinkan Anda untuk memasukkan algoritme kedaluwarsa caching Anda sendiri sehingga Anda dapat mengontrol fungsionalitas intip Anda.

Anda dapat membuat serial ke disk, database, di cluster dll ...

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.