Menggunakan MapMaker Guava

1. Pengenalan

MapMaker adalah kelas pembina di Jambu yang memudahkan pembuatan peta yang selamat untuk benang.

Java sudah menyokong WeakHashMap untuk menggunakan Rujukan Lemah untuk kunci. Tetapi, tidak ada penyelesaian luar untuk menggunakan yang sama untuk nilai. Nasib baik, MapMaker menyediakan kaedah pembangun sederhana untuk menggunakan WeakReference untuk kedua-dua kunci dan nilai .

Dalam tutorial ini, mari kita lihat bagaimana MapMaker mempermudah membuat banyak peta dan menggunakan rujukan yang lemah.

2. Ketergantungan Maven

Pertama sekali, mari tambahkan kebergantungan Jambu Batu Google, yang terdapat di Maven Central:

 com.google.guava guava 29.0-jre 

3. Contoh Caching

Mari pertimbangkan senario mudah pelayan yang mengekalkan beberapa cache untuk pengguna: cache sesi dan cache profil.

Cache sesi tidak lama dengan entri menjadi tidak sah setelah pengguna tidak lagi aktif. Jadi cache dapat membuang entri untuk pengguna setelah objek pengguna dikumpulkan sampah.

Walau bagaimanapun, cache profil boleh mempunyai masa hidup yang lebih tinggi (TTL). Entri dalam cache profil menjadi tidak sah hanya apabila pengguna mengemas kini profilnya.

Dalam kes ini, cache dapat membuang entri hanya apabila objek profil dikumpulkan sampah.

3.1. Struktur Data

Mari buat kelas untuk mewakili entiti ini.

Kami akan mula-mula dengan pengguna:

public class User { private long id; private String name; public User(long id, String name) { this.id = id; this.name = name; } public long getId() { return id; } public String getName() { return name; } }

Kemudian sesi:

public class Session { private long id; public Session(long id) { this.id = id; } public long getId() { return id; } } 

Dan akhirnya profil:

public class Profile { private long id; private String type; public Profile(long id, String type) { this.id = id; this.type = type; } public long getId() { return id; } public String getName() { return type; } }

3.2. Membuat Cache

Mari buat contoh ConcurrentMap untuk sesi cache menggunakan kaedah makeMap :

ConcurrentMap sessionCache = new MapMaker().makeMap();

Peta yang dikembalikan tidak membenarkan nilai nol untuk kunci dan nilai.

Sekarang, mari buat satu lagi contoh ConcurrentMap untuk cache profil:

ConcurrentMap profileCache = new MapMaker().makeMap();

Perhatikan bahawa kita belum menentukan kapasiti awal untuk cache. Oleh itu, MapMaker membuat peta kapasiti 16 secara lalai.

Sekiranya kita mahu, kita boleh mengubah kapasiti menggunakan kaedah Kapasiti awal :

ConcurrentMap profileCache = new MapMaker().initialCapacity(100).makeMap();

3.3. Menukar Tahap Kesesuaian

MapMaker menetapkan nilai lalai untuk tahap serentak menjadi 4 . Walau bagaimanapun, sessionCache perlu menyokong bilangan kemas kini serentak yang lebih tinggi tanpa sebarang perbalahan.

Di sini, kaedah pembangun concurrencyLevel datang untuk menyelamatkan:

ConcurrentMap sessionCache = new MapMaker().concurrencyLevel(10).makeMap();

3.4. Menggunakan Rujukan Lemah

Peta yang kami buat di atas menggunakan rujukan yang kuat untuk kedua-dua kunci dan nilai. Jadi, catatan tetap ada di dalam peta walaupun kunci dan nilainya dikumpulkan sampah. Sebaliknya, kita harus menggunakan rujukan yang lemah.

A sessionCache kemasukan adalah tidak sah selepas kunci (objek pengguna) adalah sampah dikumpulkan. Oleh itu, mari gunakan rujukan lemah untuk kunci:

ConcurrentMap sessionCache = new MapMaker().weakKeys().makeMap();

Untuk profileCache , kita boleh menggunakan rujukan lemah untuk nilai:

ConcurrentMap profileCache = new MapMaker().weakValues().makeMap();

Apabila rujukan ini dikumpulkan sampah, Jambu biji menjamin bahawa catatan ini tidak akan disertakan dalam operasi membaca atau menulis berikutnya di peta . Walau bagaimanapun, kaedah size () kadangkala tidak konsisten dan boleh merangkumi entri ini .

4. MapMaker Internals

MapMaker membuat ConcurrentHashMap secara lalai jika rujukan lemah tidak diaktifkan . Pemeriksaan kesaksamaan berlaku melalui kaedah sama biasa.

Sekiranya kita mengaktifkan rujukan yang lemah, maka MapMaker membuat peta khusus yang diwakili oleh satu set jadual hash secara dalaman. Ia juga mempunyai ciri prestasi yang serupa dengan ConcurrentHashMap .

Walau bagaimanapun, perbezaan penting dengan WeakHashMap adalah bahawa pemeriksaan kesetaraan berlaku melalui perbandingan identiti (== dan identitiHashCode ).

5. Kesimpulan

Dalam artikel pendek ini, kami belajar bagaimana menggunakan kelas MapMaker untuk membuat peta selamat utas . Kami juga melihat bagaimana menyesuaikan peta untuk menggunakan rujukan yang lemah.

Seperti biasa, kod sumber penuh artikel terdapat di GitHub.