ב-Java סנכרון חיוני בתכנות בו-זמנית כאשר חוטים מרובים ניגשים למשאבים משותפים. זה מבטיח שרק שרשור אחד ניגש לקטע קריטי בכל פעם ומונע חוסר עקביות בנתונים. ניתן להחיל סנכרון על שיטות או בלוקים של קוד. שיטה לעומת סנכרון בלוק
גובה kat timpf
סוגי סנכרון
- סנכרון שיטה: נועל את כל השיטה כדי להבטיח שרק שרשור אחד יבצע אותה בכל פעם.
- סנכרון חסימה: נועל רק את החלק הקריטי של הקוד בתוך שיטה.
סנכרון נדרש עבור אובייקטים הניתנים לשינוי שאליהם ניתן לגשת באמצעות שרשורים מרובים. אובייקטים בלתי ניתנים לשינוי או גישה לקריאה בלבד אינם דורשים סנכרון.
סנכרון שיטה
כדי לסנכרן שיטה הוסף את מילת המפתח המסונכרנת. זה מבטיח שרק שרשור אחד יכול לבצע את השיטה בכל פעם.
דוגמה 1: שיטה לא מסונכרנת
Javaclass Line { public void getLine() { for (int i = 0; i < 3; i++) { System.out.println(i); try { Thread.sleep(100); } catch (Exception e) { System.out.println(e); } } } } class Train extends Thread { Line line; Train(Line line) { this.line = line; } public void run() { line.getLine(); } } public class Geeks { public static void main(String[] args) { Line obj = new Line(); Train t1 = new Train(obj); Train t2 = new Train(obj); t1.start(); t2.start(); } }
תְפוּקָה
0 0 1 1 2 2
הֶסבֵּר: חוטים t1 ו-t2 ניגשים לשיטה בו זמנית וגורמים לפלט מעורב.
דוגמה 2: שיטה מסונכרנת
Javaclass Line { synchronized public void getLine() { for (int i = 0; i < 3; i++) { System.out.println(i); try { Thread.sleep(100); } catch (Exception e) { System.out.println(e); } } } } class Train extends Thread { Line line; Train(Line line) { this.line = line; } public void run() { line.getLine(); } } public class Geeks { public static void main(String[] args) { Line obj = new Line(); Train t1 = new Train(obj); Train t2 = new Train(obj); t1.start(); t2.start(); } }
תְפוּקָה
0 1 2 0 1 2
הֶסבֵּר: רק שרשור אחד מבצע את השיטה בכל פעם ומבטיח עקביות נתונים.
אתרי סרטים דומים ל-123movies
חסימת סנכרון
נעשה שימוש בסנכרון בלוקים כאשר רק חלק מהשיטה מכיל קוד קריטי. זה משפר את הביצועים בכך שהוא מאפשר לשרשורים להפעיל קוד לא קריטי במקביל.
דוגמה: בלוק מסונכרן
Javaimport java.util.*; class Geek { String name = ''; public int count = 0; public void geekName(String geek List<String> list) { synchronized(this) { name = geek; count++; } list.add(geek); } } public class GFG { public static void main(String[] args) { Geek gk = new Geek(); List<String> list = new ArrayList<>(); gk.geekName('Mohit' list); System.out.println(gk.name); } }
תְפוּקָה
Mohit
הֶסבֵּר: רק השם והספירה של עדכון הבלוק מסונכרנים. הוספת שמות לרשימה פועלת במקביל.
שיטה לעומת סנכרון בלוקים
| תכונה | סנכרון שיטה | חסימת סנכרון |
|---|---|---|
| תְחוּם | נועל את כל השיטה | נועל רק את גוש הקוד הספציפי |
| ביצועים | יכול לגרום לחסימה מיותרת עבור קוד לא קריטי | יעיל יותר רק קטעים קריטיים מסונכרנים |
| לִנְעוֹל | רוכש את המנעול על אובייקט השיטה | רוכש את המנעול על האובייקט או המחלקה שצוינו בבלוק |
| גְמִישׁוּת | פחות גמיש כל השיטה נעולה | גמיש יותר מאפשר סנכרון סלקטיבי |
נקודות חשובות
- שרשור הנכנס לשיטה/בלוק מסונכרנים רוכש נעילה והוא משחרר אותו ביציאה.
- שיטות/בלוקים של מופע: רכישת נעילה ברמת האובייקט.
- שיטות/בלוקים סטטיים: רכישת נעילה ברמת הכיתה.
- סנכרון על אובייקטים null זורק NullPointerException.
- wait() notify() ו-notifyAll() הן שיטות מפתח בסנכרון.
- הימנע מסנכרון שדות לא סופיים כדי למנוע מהשרשורים לנעול אובייקטים שונים.
- לא ניתן להחיל מילת מפתח מסונכרנת על משתנים.
יתרונות
- מבטיח אי הכללה הדדית עבור משאבים משותפים בתוכניות ריבוי הליכי.
- הן מופע מסונכרן והן שיטות סטטיות יכולות לפעול במקביל מכיוון שהן נועלות אובייקטים שונים.
מגבלות
- מונע קריאה בו-זמנית ומגביל את המקיפות.
- שיטות מסונכרנות עלולות לפגוע בביצועים. העדיפו סנכרון בלוקים לקטעים קריטיים בלבד.