PracticU

הדגמה של Singleton - חלק 10

בלי כתוביותעם כתוביות
PracticU › קורס Design Patterns › הדגמה של Singleton - חלק 10
מילון מושגים:
Singleton - דפוס עיצוב שמבטיח שממחלקה מסוימת יהיה מופע אחד בלבד, עם נקודת גישה גלובלית אליו.
קומפיילר - תוכנה שממירה קוד מקור שנכתב בשפת תכנות לקוד שהמחשב יכול להריץ, ומדווחת על שגיאות תחביר.
מאפיין - תכונה שמצמידים לרכיב ומתארת אותו או את התנהגותו, למשל מאפיין של תגית HTML או שדה באובייקט.
אובייקט - יחידה בתכנות מונחה עצמים שמאגדת נתונים (תכונות) ופעולות (מתודות). נוצר בדרך כלל ממחלקה המשמשת כתבנית.
C# - שפת תכנות מונחית עצמים של מיקרוסופט, המשמשת בעיקר לפיתוח יישומים על פלטפורמת .NET.

הדגמה של Singleton - חלק 10
השיעור פותר את הבעיה מהשיעור הקודם ומראה איך מונעים מחוטים מרובים ליצור סינגלטון פעמיים בעזרת נעילה.
הפתרון
1. זיהוי הבעיה: כשחוט מקבל תשובה null ומתחיל להקצות, חוט אחר יכול לקבל את אותה תשובה באותו זמן. לכן כל אזור הבדיקה וההקצאה צריך להיות מוגן.
2. בלוק lock: המרצה עוטף את אזור היצירה בבלוק lock, כך שחוט אחד בלבד נכנס בכל רגע, והשני ממתין בשער.
3. מנעול סטטי: המנעול אינו יכול להיות this, משום שהמהדר דוחה את המילה this במאפיין או בשדה סטטי. לכן מגדירים שדה סטטי פרטי מסוג object בשם sync ומשתמשים בו כמנעול.
4. התוצאה: החוט שנכנס ראשון יוצר את האובייקט ומשחרר את המנעול ביציאה. החוט שמגיע אחריו מוצא שהערך כבר אינו null ומחזיר את האובייקט הקיים.
הדגמה בתוכנית קטנה
עם נקודת עצירה בתוך הבלוק רואים שחוט אחד מחזיק את המנעול, וחוט אחר מושהה בניסיון לפתוח אותו. המרצה מציין שההתנהגות הזו נלמדת לעומק בקורס Advanced C#, שם מלמדים חוטים ונעילה.
תרגיל
בשיעור מוצג גם תרגיל במערכת הגדולה: המשתמש בוחר מיקרופון 0, 1 או 2, ובחירה במספר גבוה יותר מפעילה במקביל את כל ההתקנים עד המספר שנבחר, בחוטים נפרדים. מטרת התרגיל היא לייצר את התקלה ולתקן אותה.
בתום השיעור הסטודנט יודע לנעול אזור יצירה משותף בעזרת שדה נעילה סטטי, ומסביר מדוע הנעילה מונעת יצירה כפולה.

פרקי ההרצאה: הדגמה של Singleton - חלק 10

  1. 00:00

    סיכום הבעיה: שני Threads יוצרים מופע כפול

  2. 00:31

    מקום התקלה: בדיקת null בזמן היצירה

  3. 01:12

    הרעיון: אזור נעול שנכנס אליו Thread אחד

  4. 02:34

    עטיפת יצירת המופע בבלוק lock

  5. 03:59

    שדה סטטי פרטי כאובייקט נעילה

  6. 04:39

    יצירת אובייקט sync כמנעול

  7. 05:57

    הרצה: Thread ראשון נכנס והשני ממתין

  8. 06:39

    שחרור המנעול והמשך הפעלת ה-Thread

תמלול ההרצאה: הדגמה של Singleton - חלק 10

הטקסט המלא של הדקות הראשונות בהרצאה «הדגמה של Singleton - חלק 10» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.

  1. 00:07

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

  2. 00:31

    אז נשאלה, שאלנו שאלה, מה הפתרון לדבר הזה? ואיך אנחנו מונעים כזאת תקלה בעצם? אז היום אנחנו נפתור את הבעיה הזאת. אוקיי, אז איפה בעצם הבעיה? אז הבעיה בעצם ראינו שהיא נוצרת כאשר Thread ראשון שואל את השאלה הזו, ואז מקבל תשובה חיובית, שכן, Instance אכן שווה ל-Null, והוא כבר בשורה הזו.

  3. 01:04

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

  4. 01:20

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

  5. 01:42

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

  6. 02:01

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

  7. 02:15

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

  8. 02:29

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

  9. 03:14

    לתקלה אז דאבל קליק אז הוא אומר keyword this is not valid in a static property static method or static field initializer אז לנו יש static property אנחנו בסטטיק פרופרטי בסטטיק פרופרטי this היא לא מילה וליטית היא לא מילה שמותר שיש לה משמעות בכלל יפה עכשיו כל מה שאנחנו רוצים זה איזשהו מין משהו שאפשר לנעול אודותיו אפשר להשתמש בו כמנעול

  10. 03:50

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

  11. 04:06

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

  12. 04:30

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

  13. 04:44

    כי כל אובג'קט ומה שיורש מהאובג'קט יכול להיות מנעול. אז זה יהיה אובג'קט, אבל המנעול עצמו נקרא sync שווה new object. זהו, יש לנו מנעול.

  14. 04:57

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

  15. 05:32

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

  16. 05:48

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

  17. 06:21

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

  18. 06:48

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

  19. 07:21

    אז אני מריץ, אוקיי, ה-thread, בוא נראה איזה, אודיו פרוק, בוא נראה איפה נמצא הוידאו, הוידאו נמצא ב-send והאודיו נמצא גם הוא ב-send.

  20. 07:38

    אה, כי ה-thread השני בכלל לא נכנס לאיף, ה-thread השני יכולנו לראות אותו כאן, אבל אם אני שם כאן breakpoint, ה-thread השני לא יראה ש-instance שווה ל-null.

  21. 07:52

    אתם יכולים לשחק עם זה בכל מקרה, זה תחום ששייך יותר לקורס של Advanced C-Sharp, ששם אנחנו מלמדים Threadים ונעילה, את כל הנושאים האלה של סנכרון Threadים.

  22. 08:06

    אוקיי, אז הבנו את הרעיון במערכת פשוטה קטנה

לקורס המלא: קורס Design Patterns אונליין

ההרצאה הקודמת: הדגמה של Singleton - חלק 9

הרצאות קשורות מקורסים אחרים

  • הדגמה של הרובוט
  • הדגמה של Decorators
  • הדגמה של DRS
  • הדגמה של RESTCONF

קורסים נוספים במסלול

  • קורס WinForms - תוכנות רגילות בווינדוס
  • פרויקט מעשי ב-#C - בונים מחשבון פשוט
  • פרויקט מעשי ב-#C - ספר טלפונים
  • פרויקט מעשי ב-#C - תוכנת צייר
  • קורס ADO.NET - חיבור אתר למסד נתונים
  • קורס תכנות מתקדם - #Advanced .NET C