Thread`ים - קרן כליף
Download
Report
Transcript Thread`ים - קרן כליף
קורס Javaמתקדם
'Threadים
קרן כליף
2 ©Keren Kalif | מתקדםJava | thread
...למקרה ואנחנו עדיין לא מכירים
http://qph.is.quoracdn.net/main-qimg-e0c9dafb319150b6c6d9816047ed9eae?convert_to_webp=true
3 ©Keren Kalif | מתקדםJava | thread
תיאום ציפיות מהקורס
http://www.1stwebdesigner.com/wp-content/uploads/2011/10/tan_lines_of_a_programmer2.jpg
4 ©Keren Kalif | מתקדםJava | thread
:ביחידה זו נלמד
ותכונותיוThread
Runnable הממשק
'יםthread מצבים של
deadlock - וracing :סינכרון תהליכים
סמפורים
Condition+Lock מוניטור ע"י
ArrayBlockingQueue
ExecuterService 'ים ע"יthread -הגבלת מספר ה
Callable ע"י הממשקthread -קבלת ערך מ
CountDownLatch - וCyclicBarrier :'יםthread המתנה לכמות מסויימת של
אובייקט אנונימי
אלגוריתמי נעילה
Java | threadמתקדם | 5 ©Keren Kalif
תהליכים ('Threadים)
עד היום כל התוכניות שלנו רצו בתהליך אחד
o
כלומר ,התוכנית לא הסתיימה עד אשר ה main -סיים לרוץ ,והפעולות בוצעו אחת אחרי-
השניה ,באופן סינכרוני
ביחידה זו נראה כיצד ניתן להריץ כמה פעולות בו-זמנית
– Threadאובייקט אשר מבצע פעולה באופן אסינכרוני
בעזרת מנגנון זה התוכנית הראשית ( )processתוכל להריץ כמה פעולות
( )threadבמקביל :למשל גם שעון מתחלף ,גם הורדת קובץ וגם אינטראקציה עם
המשתמש
Java | threadמתקדם | 6 ©Keren Kalif
דוגמא לתוכנית עם 'Threadים
ניתן לראות בפלט שהפונקציות רצו "יחד"
Java | threadמתקדם | 7 ©Keren Kalif
דוגמא למוטיבציה
המוטיבציה :כאשר יש פעולות שלוקחות
הרבה זמן ולא רוצים שהתוכנית "תתקע"
השליטה חוזרת ל main -רק
לאחר שהפונקציה הסתיימה
השליטה חוזרת ל-
mainבאופן מיידי
Java | threadמתקדם | 8 ©Keren Kalif
כיצד מריצים thread
יש לרשת מהמחלקה Thread
ולדרוס את השיטה run
ב main -נייצר אובייקט ממחלקה שיורשת מ-
Threadונפעיל את השיטה ,startהמריצה
את הקוד בתהליך נפרד ואסינכרוני
הפעלה באופן ישיר של השיטה runתפעיל
אותה באופן רגיל (סינכרוני ובאותו תהליך)
Java | threadמתקדם | 9 ©Keren Kalif
מופעים מרובים
יתכן בתוכנית מחלקת threadאחת עם מופעים רבים .כל מופע יטפל בבקשה
שונה באמצעות קוד זהה:
o
למשל threadהמטפל ברישום לקוחות חדשים .בהחלט ניתן לטפל ברישום כמה לקוחות
בו-זמנית.
מחלקות threadשונות שרצות במקביל וכל אחת מבצעת משהו שונה:
o
הורדת קבצים ,תקשורת מול אתר מרוחק ,טיפול בלקוחות וכד'
Java | threadמתקדם | 10 ©Keren Kalif
מימוש Runnable
בשפת JAVAהרי ניתן לרשת ממחלקה אחת בלבד
בצורה הנוכחית ,אם נרצה שמחלקה מסויימת תפעל ב thread -נפרד אין לנו
אפשרות ,במקרה הצורך ,לרשת ממחלקה נוספת
לכן נממש את הממשק Runnable
Java | threadמתקדם | 11 ©Keren Kalif
דוגמא
נייצר משתנה מטיפוס Runnableונייצר Thread
המקבל כפרמטר משתנה מטיפוס הממשק
Java | threadמתקדם | 12 ©Keren Kalif
אובייקט אנונימי
יצירת אובייקט זמני מטיפוס
Runnableומימוש השיטה run
Java | threadמתקדם | 13 ©Keren Kalif
אובייקט אנונימי המשתמש במשתנה חיצוני
על מנת לגשת למשתנה מחוץ לאובייקט
האנונימי ,יש להגדירו כfinal -
Java | threadמתקדם | 14 ©Keren Kalif
מיפוי הזיכרון
כאשר מריצים תוכנית mainלמעשה ישנו תהליך ראשי ( )processעם משאבים
יחודיים ,ובפרט מרחב זיכרון
בתוך התהליך המרכזי יש לפחות threadאחד
threadגם נקרא light-weight process
כל ה'thread -ים באותו processחולקים את המשאבים של הprocess -
שממנו נוצרו
o
בניגוד ל'process -ים שאינם חולקים זיכרון
15 ©Keren Kalif | מתקדםJava | thread
'יםthread - מורכב מprocess כמעט כל
Java | threadמתקדם | 16 ©Keren Kalif
)1( priority
לכל threadיש עדיפות מ 1 -עד .10ב"מ היא .5ככל שהעדיפות יותר גבוהה כך
ה thread -יועדף בעת ההרצה
העדיפות של ה-
threadהראשי
ערך ב"מ .כלומר פקודה
זו כרגע מיותרת.
העדיפות של ה-
threadשיצרתי
בגלל שלשני ה'thread -ים עדיפות
זהה ,ניתן לראות שהם רצו במקביל
Java | threadמתקדם | 17 ©Keren Kalif
מתן ערך עדיפות נמוך
ניתן לראות שהגלל של thread -יש עדיפות
נמוכה הוא רץ אחרי ה thread -הראשי
Java | threadמתקדם | 18 ©Keren Kalif
מתן ערך עדיפות גבוה
ניתן לראות שהגלל של thread -יש עדיפות
גבוהה ,כאשר הוא נכנס לפעולה הוא רץ יותר זמן
19 ©Keren Kalif | מתקדםJava | thread
thread מידע על
thread -שם ה
עדיפות
thread -שם ב"מ ל
process -שם ה
Java | threadמתקדם | 20 ©Keren Kalif
מוטיבציה לjoin -
נגיע לשורה זו לפני שה-
'threadים יסיימו את פעולתם
Java | threadמתקדם | 21 ©Keren Kalif
שימוש בjoin -
נגיע לשורה זו רק אחרי שה-
'threadים יסיימו את פעולתם
Java | threadמתקדם | 22 ©Keren Kalif
כך לא נעצור thread
בצורה זו הורגים את הthread -
אפילו אם לא סיים את פעולתו...
23 ©Keren Kalif | מתקדםJava | thread
כך כן נעצור אותו
thread -ה
Java | threadמתקדם | 24 ©Keren Kalif
המתודה interrupt
()1
נגיע לפה אם הthread -
יופסק ע"י interrupt
נשים לב שה thread -אינו חייב
להסתיים בעקבות השימוש בinterrupt -
Java | threadמתקדם | 25 ©Keren Kalif
המתודה interrupt
()2
ממתינה לסיום מקסימום שניה
הפסקת פעולת ה thread -ע"י interrupt
גרועה כמו ,stopגם תהייה
deprecatedמתישהו
האם הthread -
עדיין פעיל
Java | threadמתקדם | 26 ©Keren Kalif
מצבים של thread
יצירת משתנה
מטיפוס thread
מערכת ההפעלה קובעת מתי
ה thread -יקבל זמן ריצה
הפעלת השיטה start
מעבירה את הthread -
למצב המוכן לפעולה
ה thread -יכול
להשהות את פעולתו
ה thread -מסיים
את פעולתו
התרשים נלקח מ:
http://www.roseindia.net/java/thread/life-cycle-of-threads.shtml
27 ©Keren Kalif | מתקדםJava | thread
runnable אינוthread -מצבים שונים בהם ה
מרדים את עצמו לזמן מסויים:Sleeping
אחר יסתייםthread - מחכה ש:Blocked for Join Completion
מחכה למשאב:Blocked for I/O
אחרthread - מחכה להתרעה מ:Waiting for Notification
אחר ישחרר נעילהthread - מחכה ש:Blocked for Lock Acquisition
:התרשים נלקח מ
http://www.roseindia.net/java/thread/life-cycle-of-threads.shtml
Java | threadמתקדם | 28 ©Keren Kalif
דוגמאות למעבר בין sleep/runnable/run
באמצעות sleepנגרום לתוכנית "לנוח" ,ולא
בלולאת forהתופסת את זמן ה.CPU -
ניתן לראות מעבר לתהליך אחר.
Java | threadמתקדם | 29 ©Keren Kalif
סינכרון תהליכים -הבעיה
ניתן לראות ש Thread-1 -התחיל את פעולתו ,והיא כנראה
הופסקה באמצע :הערך לפני ההגדלה הינו 2ואחריה 8
Java | threadמתקדם | 30 ©Keren Kalif
סינכרון תהליכים – הפלט הרצוי
ניתן לראות שריצת השיטה runעבור כל
אוביקט לא הופסקה באמצע (ערך ה-
counterלפני ואחרי ההגדלה עוקב)
כדי שרצף הפקודות בשיטה runלא יקטעו
באמצע ,יש להגדיר אותם כקטע קוד קריטי
Java | threadמתקדם | 31 ©Keren Kalif
פתרון
התכונה theMutex
משותפת לכל המופעים
הגדרת הקוד שבבלוק כקטע
קריטי ,ולכן לא יקטע באמצע
מאחר ולא ניתן לבצע נעילה על אותו אובייקט בו"ז ,כל threadשיגיע ל-
runיאלץ לחכות שהקטע הקריטי יסתיים ,עד אשר הנעילה תהייה בידיו.
Java | threadמתקדם | 32 ©Keren Kalif
תרגיל
יש לדמות מערכת של שדה תעופה:
o
לכל מטוס 3מצבים :המראה ,טיסה
ונחיתה
o
רק מטוס אחד יכול להיות בהמראה או
בנחיתה ברגע נתון בשדה"ת
o
יש לסגור את שדה התעופה לאחר שכל
המטוסים סיימו לנחות
o
יש להקפיד על מודולוריות וחוקי תכנות
של OOP
הנחיות :יש להשתמש
במנגנון של synchronized
הפתרון בexe1_airport -
Java | threadמתקדם | 33 ©Keren Kalif
waitוnotify -
לעיתים נרצה ש thread -מסויים ישהה את פעולתו עד אשר threadאחר יבצע
פעולה מסויימת
ניתן להגדיר ל thread -להיכנס למצב waitשיופסק לאחר ש thread -אחר ישלח
את ההודעה notify
שימושי לצורך סינכרון בין תהליכים
דוגמא:
o
אני מכינה עוגה וחסר לי קמח
o
אני ארצה להשהות את תהליך ההכנה עד אשר יביאו לי קמח
o
אני ארצה שיודיעו לי כשהקמח הגיע כדי שאוכל להמשיך לעבוד
Java | threadמתקדם | 34 ©Keren Kalif
דוגמא :המחלקות ()1
פקודת waitתמיד תהייה עטופת בבלוק
synchronizedעם האובייקט שמחכה.
הפעלת השיטה notifyעל אובייקט זה תסיים
את פעולת ה.wait -
Java | threadמתקדם | 35 ©Keren Kalif
דוגמא :המחלקות ()2
מחזיקה כפרמטר את האובייקט
שצריך "להעיר" מwait -
את הפעולה notifyנפעיל על האובייקט שאותו נרצה להעיר.
יש לעטוף פקודה זו בבלוק synchronizedעל האובייקט
שאותו נעיר ,אחרת תתקבל החריגה
IllegalMonitorStateException
Java | threadמתקדם | 36 ©Keren Kalif
דוגמא :הmain -
הקישור עבור הסינכרון
בין 2ה'thread -ים
Java | threadמתקדם | 37 ©Keren Kalif
בלוק או שיטת synchronized
כאשר האובייקט לסינכרון הוא האובייקט המפעיל ( ,)thisניתן
להגדיר את כל השיטה כ.synchronized -
אופציה זו פחות עדיפה כי אז קטע הנעילה יותר גדול ,ונעדיף למקד
אותו רק לקטע הקוד הקריטי.
Java | threadמתקדם | 38 ©Keren Kalif
מה קורה למשאב הקריטי בזמן )1( ?wait
כאשר אנחנו בתוך waitהמשאב הקריטי משתחרר
עד אשר ה wait -ישתחרר באמצעות notify
Java | threadמתקדם | 39 ©Keren Kalif
מה קורה למשאב הקריטי בזמן )2( ?wait
נשים לב מתי מהתודה fooמופעלת
Java | threadמתקדם | 40 ©Keren Kalif
תרגיל
יש לדמות מערכת של שדה תעופה:
o
לכל מטוס 3מצבים :המראה ,טיסה
ונחיתה
o
רק מטוס אחד יכול להיות בהמראה או
בנחיתה ברגע נתון בשדה"ת
o
יש לסגור את שדה התעופה לאחר שכל
המטוסים סיימו לנחות
הנחיות :הפעם אין לבצע נעילה על שדה"ת ,אלא לבצע waitכאשר מחכים למסלול
בשדה התעופה .אחריות השדה ליידע את מי שמחכה כאשר המסלול מתפנה.
הפתרון בexe2_airport -
Java | threadמתקדם | 41 ©Keren Kalif
בעיות בעבודה עם 'threadים
– Racingכאשר התוצאה של פעולה מסויימת תלויה בתזמון פעולה בthread -
אחר ,תלות במשאב משותף .אם אין סינכרון יכולה להיווצר בעיה.
o
לדוגמא :מדור משאבי אנוש מעדכן את ערך המשכורות ומחלקת שכר צריכה להנפיק את
המשכורות .אם מחלקת השכר תנפיק את המשכורות לפני העדכון של משאבי האנוש
תהייה בעיה.
– Starvingכאשר threadמסויים אינו מקבל זמן לריצה ע"י ה .CPU -יכול
לקרות בגלל בעיה בעדיפויות של ה'thread -ים.
– Deadlockכאשר 'thread 2ים אינם יכולים להמשיך בפעילותם מאחר וכל
אחד ממתין לשני (למשל בעיית אגו :אני לא אתקשר אליך עד אשר אתה תתקשר
אליי ,וההיפך)...
Java | threadמתקדם | 42 ©Keren Kalif
דוגמא לracing -
שני המופעים תלויים במשתנה זה ,אבל אחד הפריע
לשני באמצע (ראו את הערך 0פעמיים בפלט)
Java | threadמתקדם | 43 ©Keren Kalif
דוגמא לdeadlock -
דוגמאת הפילוסופים הסינים:
o
5פילוסופים סינים יושבים מסביב לשולחן האוכל .מול כל אחד יש צלחת ,ובין כל 2צלחות
יש .chopstick
o
כדי לאכול כל פילוסוף צריך ,chopstick 2והוא יכול לקחת רק את זה שמונח מימין או
משמאל לצלחת שלו.
o
אם כל פילוסוף יקח את המקל שלימינו ,ולא יניח אותו עד שיסיים לאכול ,לעולם אף פילוסוף
לא יוכל לאכול ,וזהו למעשה deadlock
התמונה לקוחה מ:
_http://en.wikipedia.org/wiki/Dining_philosophers
problem
44 ©Keren Kalif | מתקדםJava | thread
מימוש
Java | threadמתקדם | 45 ©Keren Kalif
השיטה tryToEat
מחכה למזלג ואז נועל אותו
שחרור הנעילות על המזלגות
בסיום הבלוקים
Java | threadמתקדם | 46 ©Keren Kalif
הmain -
הפתרון :לנעול מזלג רק אם 2המזלגות
פנויים .אפשר להשתמש לצורך כך באובייקט
Semaphoreהמאפשר לבדוק נעילה.
לכל הפילוסופים יש את המזלג השמאלי ,וכולם מחכים לימני..
יחכו לנצח כי אף אחד לא משחרר...
47 ©Keren Kalif | מתקדםJava | thread
Semaphore עבודה עם
Java | threadמתקדם | 48 ©Keren Kalif
השיטה tryToEatבמימוש סמפור
מחכה עד שניתן לקבל נעילה על האובייקט
בודקת האם ניתן לקבל נעילה
אם לא ניתן לקבל נעילה גם על המזלג הימני,
משחררת את השמאלי ,ויוצאת מהשיטה.
runתנסה להפעיל שיטה זו שוב בהמשך.
Java | threadמתקדם | 49 ©Keren Kalif
הmain -
כמה אובייקטים יכולים לבצע
את הנעילה בו"ז ,והאם סדר
הפעולה שלהם הוא FIFO
50 ©Keren Kalif | מתקדםJava | thread
צרכן-בעיית היצרן
51 ©Keren Kalif | מתקדםJava | thread
52 ©Keren Kalif | מתקדםJava | thread
wait + notify באמצעותCubyHole מימוש
Java | threadמתקדם | 53 ©Keren Kalif
ממתין עד אשר יהיה מקום בקופסה
מודיע שיש עוגיות בקופסה
Java | threadמתקדם | 54 ©Keren Kalif
ממתין שיהיו עוגיות בקופסה
מודיע שיש מקום בקופסה
Java | threadמתקדם | 55 ©Keren Kalif
מנגנון סינכרון ע"י Lock + Condition
Monitorהוא מנגנון המסנכרן בין לפחות שני 'threadים ,ומשתמש באובייקטים
Lockו Condition -הקיימים בשפה
56 ©Keren Kalif | מתקדםJava | thread
Lock הממשק
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html
57 ©Keren Kalif | מתקדםJava | thread
Condition הממשק
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html
58 ©Keren Kalif | מתקדםJava | thread
Lock + Condition באמצעותCubyHole מימוש
59 ©Keren Kalif | מתקדםJava | thread
Producer / Consumer - ולא בתוך הCubyHole -הנעילה נמצאת בתוך ה
?מדוע
60 ©Keren Kalif | מתקדםJava | thread
61 ©Keren Kalif | מתקדםJava | thread
BlockingQueue הממשק
הצלחת-לממשק זה יש מתודות המטפלות באופן שונה במקרה של אי
הכנסה מיידית/הסרה
)Blocking( חסימהtrue/false החזרת
timeout
זריקת חריגה
offer(obj, timeout, unit)
put(obj)
offer(obj)
add(obj)
הוספה
poll(timeout, unit)
take(obj)
poll(obj)
remove(obj)
הסרה
ArrayBlockingQueue לממשק זה מספר מימושים ובינהם
62 ©Keren Kalif | מתקדםJava | thread
BlockingQueue באמצעותCubyHole מימוש
63 ©Keren Kalif | מתקדםJava | thread
BlockingQueue באמצעותCubyHole מימוש
64 ©Keren Kalif | מתקדםJava | thread
דוגמת פלט
Java | threadמתקדם | 65 ©Keren Kalif
Synchronized Collections
האוספים ב java.util -מגרסה ( 1.5אלו המשתמשים ב )generics -אינם
,ThreadSafeמשמע ניתן להסיר ולהוסיף איברים בו"ז ,מה שכמובן עלול לגרום
במקרים מסויימים לבעיות
o
האוספים הישנים (שהוגדרו ב JDK1 -הם כן ThreadSafeאך כמעט ואינם בשימוש)
ניתן להגדיר Synchronized Collectionע"י יצירת אוסף חדש שעוטף את
האוסף המקורי ,ושם ב synchronized -את המתודות addוremove -
אוספים אלו אינם מוגדרים כטיפוסים חדשים ,אלא נוצרים ע"י שיטות עזר
Java | threadמתקדם | 66 ©Keren Kalif
דוגמה
זוהי הפנייה לאותה רשימה
עבודה עם איטרטור צריכה להיות
בתוך בלוק synchronized
Java | threadמתקדם | 67 ©Keren Kalif
הגבלת מספר ה'thread -ים
במקרה בו נרצה להגביל את כמות ה'thread -ים הרצים במקביל נשתמש ב-
ExecuterService
דוגמא:
o
תור במרכז שירות /קופאיות בסופר :בכל רגע נתון מטפלים רק ב X -לקוחות ובשלב מסויים
רוצים לסגור את התור לקבלת קהל נוסף
68 ©Keren Kalif | מתקדםJava | thread
הלקוח:דוגמא
Java | threadמתקדם | 69 ©Keren Kalif
דוגמא :הmain -
לחכות עד שכל ה'thread -ים
יסיימו או 10שניות ,מה שבא קודם.
ניתן לראות שאחרי ש 6 -לקוחות נכנסים החנות
לא מקבלת יותר לקוחות.
וכן אחרי סיום טיפול בלקוח מתחיל טיפול באחר.
Java | threadמתקדם | 70 ©Keren Kalif
המחלקה Executors
יש לה מתודות סטטיות ליצירת סוג ה ExecutorService -מהסוג המבוקש,
ובינהן:
o
newFixedThreadPoolהמגדיר כמה 'threadים יוכלו לעבוד בו-זמנית
o
newCachedThreadPoolהמאפשר שימוש בלתי מוגבל של 'threadים ,אבל יודע
להשתמש בזכרון של 'threadים שכבר סיימו עבודתם (במקום יצירת אובייקט חדש עבור כל
)thread
Java | threadמתקדם | 71 ©Keren Kalif
הממשק :Callableקבלת ערך מ thread -לאחר שסיים את ריצתו
עד כה ה'thread -ים הסתיימו ולא ביקשנו מהם ערך מוחזר
כדי לקבל את הערך המוחזר של threadמסויים ,יש לחכות שקודם כל ה-
'threadים יסיימו את ריצתם ,כי אחרת לא נדע האם ה thread -כבר סיים את
פעולתו וניתן לקבל את הערך שחישב
ניתן להשתמש בממשק ,Callableבמקום בממשק ,Runnableאשר בו
המתודה להרצה ( )callמחזירה ערך ,בניגוד למתודה runשמחזירה void
בנוסף ,המתודה callיכולה לזרוק חריגה ,בעוד שהחתימה של runאינה
מאפשרת זאת
הממשק Callableהצטרף לפשה רק החלק מגרסה 1.5ומטעמי תאימות לאחור
הממשק Runnableנותר קיים
72 ©Keren Kalif | מתקדםJava | thread
-דוגמא לשימוש ב
Runnable
Java | threadמתקדם | 73 ©Keren Kalif
דוגמה לשימוש בCallable -
ניתן לקבל את ערכו של threadגם בלי לחכות לסיום כל שאר ה'thread -ים
יש לממש את הממשק ,ולהגדיר מהו
טיפוס הערך המוחזר בסיום ההרצה
טיפוס הערך המוחזר כפי שהוגדר
בשורת מימוש הממשק
השיטה רצה ב thread -נפרד
ומחזירה ערך לאחר סיומה
Java | threadמתקדם | 74 ©Keren Kalif
הרצת משתנה Callableאינה באמצעות threadאלא
באמצעות השיטה submitשל ExecuterService
איחסון כל ההרצות שעבורן מחכים לתשובה
מסיים את פעולת ה,ServiceExecuter -
אחרת ה main -אינו מסתיים
מחכה שתתקבל התשובה .כלומר התשובות
יהיו לפי סדר יצירת האובייקטים.
Java | threadמתקדם | 75 ©Keren Kalif
ניתן לראות שסדר התשובות
הוא לפי סדר יצירת האובייקטים
Java | threadמתקדם | 76 ©Keren Kalif
בעיית הLost-Wakeup Problem -
היפהייפיה הנרדמת ישנה עד אשר הנסיך שולח לה נשיקה .אם הוא שלח נשיקה
לפני שהיא נרדמה ,היא לעולם לא תתעורר!
כלומר ,כאשר נשלח notifyלפני שהופעל ה..wait -
77 ©Keren Kalif | מתקדםJava | thread
78 ©Keren Kalif | מתקדםJava | thread
79 ©Keren Kalif | מתקדםJava | thread
Java | threadמתקדם | 80 ©Keren Kalif
CountDownLatch
אובייקט המאפשר ל thread -להמתין עד אשר 'threadים אחרים יתחילו/יסיימו
את עבודתם
משמש לצורכי סינכרון
o
למשל ,שהנסיך לא ישלח נשיקה לפני שהיפהיפיה הנרדמת הלכה לישון
Java | threadמתקדם | 81 ©Keren Kalif
– FairyTaleגרסה מתוקנת
מסמן שהפעולה בוצעה
82 ©Keren Kalif | מתקדםJava | thread
על האובייקטcountDown מחכה שתופעל
83 ©Keren Kalif | מתקדםJava | thread
Java | threadמתקדם | 84 ©Keren Kalif
שימושים לסנכרון זה
ניתן להשתמש באובייקט זה כאשר יש שני 'threadים שמאותחלים ביחד ,אך
רוצים לדאוג שה start -של אחד יחל רק לאחר שהשני סיים
דוגמא:
o
בהינתן threadהמייצג מכונית ו thread -המייצג שער ,נרצה לדאוג שה thread -של
השער יתחיל פעולתו לפני המכונית
o
לוגית ,הגיוני שקודם יש שערים ,ואח"כ מכוניות
o
אפילו אם קוראים ל start -ל thread -של השער לפני ה start -של ה thread -של
המכונית ,איך הכרח שהשער ירוץ קודם
o
באמצעות CountDownLatchניתן לדאוג לכך
Java | threadמתקדם | 85 ©Keren Kalif
תרגיל
יש לדמות סיטואציה של ישיבה:
o
יש להמתין ל chairman -שיפתח את הישיבה
o
יש להמתין ל 3 -דירקטורים שיגיעו לישיבה
o
לא ניתן להתחיל את הישיבה עד אשר הודלק המקרן
Mainלדוגמה והפלט בשקפים הבאים
86 ©Keren Kalif | מתקדםJava | thread
לדוגמהmain -ה
להורדהmain -קובץ ה
87 ©Keren Kalif | מתקדםJava | thread
פלט אפשרי לתוכנית
Java | threadמתקדם | 88 ©Keren Kalif
CyclicBarrier
אובייקט סינכרון דומה לCountDownLatch -
העבודה של האובייקט הינה מחזורית ,לאחר שהתור התמלא וכל האובייקטים
שבו סיימו עבודתם ,הוא ימתין לסיבוב נוסף
o
CyclicBarrierמאפשר ריצת ה run -של threadיותר מפעם אחת
o
כמו ה CountDownLatch -אבל עובד במחזוריות
למשל:
o
מונית שירות מתחילה את המסלול רק לאחר שיש מינימום נוסעים ,ואחרי סיבוב אחד
מבצעת סיבוב נוסף
o
מתקן בלונה-פארק מתחיל לפעול רק לאחר שיש מינימום מבלים ,ושוב ושוב
Java | threadמתקדם | 89 ©Keren Kalif
– CyclicBarrierדוגמא -המונית
נראה בהמשך שה run -יופעל יותר
מפעם אחת לאובייקט Taxiיחיד
90 ©Keren Kalif | מתקדםJava | thread
הנוסע- – דוגמאCyclicBarrier
מחכה שכל המכסה תתמלא
Java | threadמתקדם | 91 ©Keren Kalif
main –CyclicBarrier
ה thread -שירוץ
מספר האובייקטים שצריכים
להצטבר עבור התחלת הפעולה
אם הלולאה תרוץ 7פעמים ,התוכנית לא תסתיים,
מאחר ויהיה ניסיון למלא את המונית עבור לקוח זה..
Java | threadמתקדם | 92 ©Keren Kalif
- CyclicBarrierהפלט
– פלט
ניתן לראות שה run -של Taxi
בסיבוב השני התחיל רק לאחר
סיום ה run -של הסיבוב הראשון
Java | threadמתקדם | 93 ©Keren Kalif
מימושים של מנעולים
:ReentrantLockמאפשר לאובייקט שמחזיק במנעול להחזיקו שוב
o
המטרה היא למנוע מצב בו לאובייקט יש deadlockעם עצמו
94 ©Keren Kalif | מתקדםJava | thread
ReentrantLock מימוש של
Java | threadמתקדם | 95 ©Keren Kalif
אם האובייקט הזה הוא הנועל ,נגדיל את מספר הנעילות
אם ישנה נעילה ,ולא ע"י אובייקט זה ,יש להמתין
Java | threadמתקדם | 96 ©Keren Kalif
אם המנעול אינו מוחזק ע"י
אף אחד ,אין צורך לבצע דבר..
אם זו הנעילה האחרונה ,יש
לסמן שהנעילה הסתיימה
97 ©Keren Kalif | מתקדםJava | thread
ReadWriteLock מימוש
:מחלקות המממשות ממשק זה
)מאפשרות קוראים מרובים (שאינם משנים את המידע
o
מאפשרות כותב יחיד
o
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReadWriteLock.html
98 ©Keren Kalif | מתקדםJava | thread
ReadWriteLock מימוש
99 ©Keren Kalif | מתקדםJava | thread
Java | threadמתקדם | 100 ©Keren Kalif
נשים לב :במימוש זה ,בזמן שהכותב
מחכה ,יתכן ויכנסו קוראים נוספים ,ולכן
הכותב לעולם לא יקבל את הנעילה
Java | threadמתקדם | 101 ©Keren Kalif
נעילה הוגנתFair Readers-Writers :
במקרה בו יש קוראים רבים ,ישנו סיכוי שהכותב לעולם לא יכנס לקטע הקריטי
לכן ישנו מימוש שברגע שהכותב מבקש נעילה ,אין אפשרות כניסה לקוראים
נוספים לקטע הקריטי
102 ©Keren Kalif | מתקדםJava | thread
Fair Readers-Writers Lock implementation
103 ©Keren Kalif | מתקדםJava | thread
104 ©Keren Kalif | מתקדםJava | thread
Java | threadמתקדם | 105 ©Keren Kalif
מימוש ( Semaphoreהומצא ע"י דיקסטרה!)
למחלקת Semaphoreישנן 3מתודות מרכזיותacquire, realease, :
tryAcuire
יתרונו שהו שמאפשר נעילה זו-זמנית ע"י כמה אובייקטים
המתודה acquireהיא blockingבעוד המתודה tryAcquireהיא סינכרונית
106 ©Keren Kalif | מתקדםJava | thread
Semaphore implementation
Java | threadמתקדם | 107 ©Keren Kalif
השוואה בין שימוש ב Lock -לעומת wait+notify
אובייקט Lockמחליף את בלוק ה synchronized -והאובייקט
Conditionמחליף את שיטות אובייקט המוניטור ()wait+notify
כאשר משתמשים ב Lock -ניתן לבחור באיזה מימוש שלא להשתמש:
Reentrant, ReaderWriter, Fifoוכד'
יש הטוענים שהקוד קריא יותר כאשר משתמשים ב..Lock -
Java | threadמתקדם | 108 ©Keren Kalif
– EDTה thread -להפעלת הGUI -
את ה swing -גם נריץ ב thread -נפרד כדי שנוכל להריץ את הלוגיקה שלנו
במקביל בלי תקיעויות .כלומר ,שאם קורה אירוע בזמן ציור ה ,GUI -התוכנית לא
"תתקע"
Threadזה נקרא )EDT( Event Dispatch Thread
ה Swing -עצמו מריץ את רוב המתודות שלו ב EDT -מאחר והקוד של Swing
אינו ( Thread-Safeמשמע תיתכן פניה ועדכון בו"ז של משתנה מסויים) ,וה-
EDTדואג לסנכרון הפעולות
באפליקציות גדולות'thread ,ים אחרים ירצו לעדכן את ה ,GUI -וכדי למנוע
"תקיעות" וכדי שהעבודה תיעשה במקביל ,כל ניסיון פניה ל GUI -יהיה דרך ה-
EDT
109 ©Keren Kalif | מתקדםJava | thread
הקוד- נפרדthread - בswing -הפעלת ה
110 ©Keren Kalif | מתקדםJava | thread
:ביחידה זו למדנו
ותכונותיוThread
Runnable הממשק
'יםthread מצבים של
deadlock - וracing :סינכרון תהליכים
סמפורים
Condition+Lock מוניטור ע"י
ArrayBlockingQueue
ExecuterService 'ים ע"יthread -הגבלת מספר ה
Callable ע"י הממשקthread -קבלת ערך מ
CountDownLatch - וCyclicBarrier :'יםthread המתנה לכמות מסויימת של
אובייקט אנונימי
אלגוריתמי נעילה