logo

ConcurrentModificationException ב-Java

ConcurrentModificationException מתרחש כאשר מנסים לשנות אובייקט בו-זמנית כאשר הוא אינו מותר. יוצא מן הכלל הזה מגיע בדרך כלל כשעובדים איתו שיעורי Java Collection .

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

כוח מטמון נקי npm

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

דוגמא

 import java.awt.List; import java.util.*; public class Concurrentmodificationexception { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); Iterator it = list.iterator(); while (it.hasNext()) { Integer value = it.next(); System.out.println('List Value:' + value); if (value.equals(3)) list.remove(value); } } } 

תְפוּקָה:

ConcurrentModificationException ב-Java

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

לדוגמה-

javafx על eclipse
 import java.awt.List; import java.util.*; public class concurrentmodificationexception { public static void main(String[] args) { HashMap map = new HashMap(); map.put(1, 1); map.put(2, 2); map.put(3,3); Iterator it = map.keySet().iterator(); while(it.hasNext()) { Integer key = it.next(); System.out.println('Map Value:' + map.get(key)); if (key.equals(2)) { map.put(1, 4); } } } } 

תְפוּקָה:

 Map Value:1 Map Value:2 Map Value:3 

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

בונים של ConcurrentModificationException

ישנם 4 סוגים של בנאים של ConcurrentModificationException -

js onload
  1. public ConcurrentModificationException() -
    זה יוצר ConcurrentModificationException ללא פרמטרים.
  2. ציבורי ConcurrentModificationException(הודעה מחרוזת)
    זה יוצר ConcurrentModificationException עם הודעה מפורטת המציינת את החריגה.
  3. Public ConcurrentModificationException (גורם שניתן לזרוק)
    זה יוצר ConcurrentModificationException עם סיבה והודעה שהיא (cause==null?null:cause.toString()). הסיבה מאוחזרת מאוחר יותר על ידי ה-Throwable.getCause().
  4. Public ConcurrentModificationException(הודעה מחרוזת, סיבה שניתן לזרוק)
    זה יוצר ConcurrentModificationException עם הודעה מפורטת וסיבה. (cause==null?null:cause.toString()). ההודעה מאוחזרת מאוחר יותר על ידי Throwable.getMessage() והסיבה מאוחזרת מאוחר יותר על ידי Throwable.getCause().

כיצד להימנע מ- ConcurrentModificationException בסביבה מרובת הליכי שרשרת?

כדי להימנע מ-ConcurrentModificationException בסביבה מרובת הליכי הליכי, אנו יכולים לבצע את הדרכים הבאות-

  1. במקום לחזור על מחלקת האוסף, אנו יכולים לבצע איטרציה על המערך. בדרך זו, נוכל לעבוד טוב מאוד עם רשימות בגודל קטן, אבל זה ידלד את הביצועים אם גודל המערך גדול מאוד.
  2. דרך נוספת יכולה להיות נעילת הרשימה על ידי הכנסתה לבלוק המסונכרן. זו אינה גישה יעילה שכן המטרה היחידה של שימוש בריבוי השחלות מוותרת על ידי זה.
  3. JDK 1.5 ומעלה מספקת מחלקות ConcurrentHashMap ו-CopyOnWriteArrayList. שיעורים אלה עוזרים לנו להימנע מחריג שינוי בו-זמני.

כיצד להימנע מ- ConcurrentModificationException בסביבה עם חוט יחיד?

על ידי שימוש בפונקציה remove() של איטרטור, אתה יכול להסיר אובייקט מאובייקט אוסף בסיסי.