logo

מילת מפתח נדיפה ב-Java

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

השוואת מחרוזות ב-java

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

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

דוגמא

 class Test { static int var=5; } 

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

 class Test { static volatile int var =5; } 

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

מתי להשתמש בו?

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

נקודות חשובות

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

ההבדל בין סנכרון למילת מפתח נדיפה

מילת מפתח נדיפה אינה תחליף למילת מפתח מסונכרנת, אך היא יכולה לשמש כחלופה במקרים מסוימים. ישנם ההבדלים הבאים הם כדלקמן:

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

דוגמה למילת מפתח נדיפה

בדוגמה הבאה, הגדרנו מחלקה שמגדילה את ערך המונה. שיטת run () ב-VolatileThread.java מקבלת את הערך המעודכן ואת הערך הישן כאשר השרשור מתחיל בביצוע. במחלקה הראשית, אנו מגדירים את מערך החוטים.

VolatileData.java

 public class VolatileData { private volatile int counter = 0; public int getCounter() { return counter; } public void increaseCounter() { ++counter; //increases the value of counter by 1 } } 

VolatileThread.java

 VolatileThread.java public class VolatileThread extends Thread { private final VolatileData data; public VolatileThread(VolatileData data) { this.data = data; } @Override public void run() { int oldValue = data.getCounter(); System.out.println('[Thread ' + Thread.currentThread().getId() + ']: Old value = ' + oldValue); data.increaseCounter(); int newValue = data.getCounter(); System.out.println('[Thread ' + Thread.currentThread().getId() + ']: New value = ' + newValue); } } 

VolatileMain.java

 public class VolatileMain { private final static int noOfThreads = 2; public static void main(String[] args) throws InterruptedException { VolatileData volatileData = new VolatileData(); //object of VolatileData class Thread[] threads = new Thread[noOfThreads]; //creating Thread array for(int i = 0; i <noofthreads; ++i) threads[i]="new" volatilethread(volatiledata); for(int i="0;" < noofthreads; threads[i].start(); starts all reader threads threads[i].join(); wait for } pre> <p> <strong>Output:</strong> </p> <pre> [Thread 9]: Old value = 0 [Thread 9]: New value = 1 [Thread 10]: Old value = 1 [Thread 10]: New value = 2 </pre> <hr></noofthreads;>