באמצעות MapMaker של גויאבה

1. הקדמה

MapMaker הוא כיתת בנאים בגויאבה שמקלה על יצירת מפות הבטוחות לשרשור.

Java כבר תומכת WeakHashMap להשתמש בהפניות חלשות למפתחות. אבל, אין פיתרון מהקופסה להשתמש בו לערכים. לְמַרְבֶּה הַמַזָל, MapMaker מספק שיטות בנייה פשוטות לשימוש התייחסות חלשה גם למפתחות וגם לערכים.

במדריך זה, בואו נראה איך MapMaker מקל על יצירת מספר מפות ושימוש בהפניות חלשות.

2. תלות של Maven

ראשית, בואו נוסיף את התלות של גויאבה של גוגל, הזמינה ב- Maven Central:

 com.google.guava גויאבה 29.0-jre 

3. דוגמא למטמון

בואו ניקח בחשבון תרחיש פשוט של שרת שמתחזק כמה מטמונים עבור המשתמשים: מטמון הפעלה ומטמון פרופיל.

מטמון ההפעלה הוא קצר מועד כאשר הערכים שלו הופכים לא חוקיים לאחר שהמשתמש אינו פעיל יותר. אז המטמון יכול להסיר את הערך עבור המשתמש לאחר שאובייקט המשתמש נאסף באשפה.

עם זאת, במטמון הפרופיל יכול להיות זמן לחיות גבוה יותר (TTL). הערכים במטמון הפרופיל הופכים להיות לא חוקיים רק כאשר המשתמש מעדכן את הפרופיל שלו.

במקרה זה, המטמון יכול להסיר את הערך רק כאשר אובייקט הפרופיל נאסף אשפה.

3.1. מבני מידע

בואו ניצור שיעורים לייצוג ישויות אלה.

נתחיל תחילה עם המשתמש:

משתמש בכיתה ציבורית {מזהה פרטי ארוך; שם מחרוזת פרטי; משתמש ציבורי (מזהה ארוך, שם מחרוזת) {this.id = id; this.name = שם; } ציבורי ארוך getId () {id מזהה; } ציבורי מחרוזת getName () {return name; }}

ואז הפגישה:

מושב בכיתה ציבורית {מזהה פרטי ארוך; מושב ציבורי (מזהה ארוך) {this.id = id; } ציבורי ארוך getId () {id מזהה; }} 

ולסיום הפרופיל:

פרופיל בכיתה ציבורית {מזהה פרטי ארוך; סוג מחרוזת פרטי; פרופיל ציבורי (מזהה ארוך, סוג מחרוזת) {this.id = id; this.type = סוג; } ציבורי ארוך getId () {id מזהה; } ציבורי מחרוזת getName () {סוג החזרה; }}

3.2. יצירת המטמונים

בוא ניצור מופע של ConcurrentMap למטמון ההפעלה באמצעות makeMap שיטה:

ConcurrentMap sessionCache = MapMaker חדש (). MakeMap ();

המפה שהוחזרה אינה מאפשרת ערכי null הן למפתח והן לערך.

עכשיו בואו ניצור מופע נוסף של ConcurrentMap למטמון הפרופיל:

ConcurrentMap profileCache = MapMaker חדש (). MakeMap ();

שימו לב שלא ציינו את הקיבולת הראשונית של המטמון. כך,MapMaker יוצר מפה של קיבולת 16 כברירת מחדל.

אם נרצה נוכל לשנות את הקיבולת באמצעות ה- initialCapacity שיטה:

ConcurrentMap profileCache = MapMaker חדש (). InitialCapacity (100) .makeMap ();

3.3. שינוי רמת המקבילות

MapMaker סטים ערך ברירת המחדל עבור רמת המקביליות ל -4. אולם, ה sessionCache צריך לתמוך במספר גבוה יותר של עדכונים בו זמנית ללא כל מחלוקת.

הנה ה concurrency רמת שיטת הבנאי באה להצלה:

ConcurrentMap sessionCache = MapMaker חדש (). ConcurrencyLevel (10) .makeMap ();

3.4. שימוש בהפניות חלשות

המפות שיצרנו לעיל משתמשות בהפניות חזקות הן למפתחות והן לערכים. לכן, הערכים נשארים במפה גם אם המפתחות והערכים נאספים באשפה. עלינו להשתמש בהתייחסויות חלשות במקום.

א sessionCache הכניסה אינה חוקית לאחר שמפתח (אובייקט המשתמש) נאסף אשפה. אז בואו נשתמש בהפניות חלשות למפתחות:

ConcurrentMap sessionCache = MapMaker חדש (). חלש מפתחות (). MakeMap ();

בשביל ה profileCache, אנו יכולים להשתמש בהתייחסויות חלשות לערכים:

ConcurrentMap profileCache = MapMaker חדש (). WeakValues ​​(). MakeMap ();

כאשר הפניות הללו נאספות אשפה, גויאבה מבטיחה כי אלה ערכים לא ייכלל באף אחת מפעולות הקריאה או הכתיבה שלאחר מכן במפה. אולם, ה גודל() לפעמים השיטה עשויה להיות לא עקבית ויכולה לכלול אותם ערכים.

4. MapMaker פנימיות

MapMaker יוצר a ConcurrentHashMap כברירת מחדל אם הפניות חלשות אינן מופעלות. בדיקות השוויון מתרחשות בשיטת השוויון הרגילה.

אם נאפשר הפניות חלשות, אז MapMaker יוצר מפה מותאמת אישית מיוצג על ידי קבוצה של טבלאות hash באופן פנימי. הוא גם חולק מאפייני ביצועים דומים כמו ConcurrentHashMap.

עם זאת, הבדל חשוב עם WeakHashMap הוא שבדיקת השוויון מתרחשת באמצעות הזהות (== ו- identityHashCode) השוואות.

5. מסקנה

במאמר קצר זה למדנו כיצד להשתמש ב- MapMaker בכיתה ליצירת מפה בטוחה לשרשור. ראינו גם כיצד להתאים את המפה לשימוש בהתייחסויות חלשות.

כמו תמיד, קוד המקור המלא של המאמר זמין באתר GitHub.