מערכים וThread Safety

מערכים וThread Safety

אחרי שיישמתי ב"ה בהצלחה ריבוי נימים במחלקה שלי, נוצר בעיה (אמנם צפויה) אחרת: thread safety במערכים (במקרה שלי ArrayList). כאן נתקלתי בבלגן איסופי שאני מקווה שג'סטין יעשה בו סדר. זה בערך מה שמצאתי על הנושא בMSDN: SyncLock Collections and Synchronization (Thread Safety) Managed Threading Best Practices כעת רק כמה שאלות: א. אם ההגדרה של SyncLock היא שלא ניתן להריץ בו זמנית שני נימים של הקוד המוקף, אז מה זה עוזר במקרה של מערכים? הרי אם למשל אסרתי על המתודה של מחיקת פריט לרוץ בו זמנית, עדיין באותו הזמן יהיה ניתן להוסיף פריט... ב. וכן אם משתמשים בפונקציה ArrayList.Synchronized זה מחזיר מופע של SyncArrayList שבסך הכל מקיף כל מתודה של הArrayList המקורי בSyncLock אז חזרנו לבעיה "א"... ג. אם התשובה לשני השאלות הקודמות היא Monitor (אני מאוד מקווה שלא), אז אני לא מצליח למצוא ברשת איזו דוגמה מובנת וקריאה. אני מדגיש שוב, המטרה שלי היא שבזמן שthread אחד עובד עם המערך לא יהיה ניתן לגשת משער הthreadים לאף אחת מהמתודות או מהproperty של אותו המערך. (והthreadים יחכו בתור) תודה מראש.
 
nil ref error

באופן כללי, לא ניתן להשתמש בcollection ביותר מ thread אחד. אם אתה רוצה לעבוד איתו מכמה threads צריך לעשות lock ב _כל מקום שניגשים אליו_. זה כולל כתיבה (add / remove) וקריאה - foreach, list[1] וכ1 הלוק אמור לנול את זה ככה שרק thread אחד משנה / קורא מהמערך בזמן נתון, לא רק מתודה ספיציפית.
 
אתה בטוח שפירשת נכון את SyncLock?

הנה מMSDN בנושא: The SyncLock statement ensures that multiple threads do not execute the statement block at the same time. SyncLock prevents each thread from entering the block until no other thread is executing it .... לא ראיתי שכתוב כאן שהמבנה נועל את המשתנה/מערך אלא שהמבנה מונע משני נימים להריץ את אותו הקטע קוד בו זמנית! כמובן שאם כך לא מובן למה צריך לציין ב SyncLock שם של אובייקט... (ואולי זה מקור הטעות...) בכל מקרה תקנו אותי אם אני טועה... הנה המקור בMSDN
 
Nil ref error

והנה דוגמה:
public void AddItem(Item item) { lock(list) { list.Add(Item); } } public void PrintList() { lock(list) { foreach ... } }​
 

gewitter

New member
שאלה

אם אני יודע שיש _רק_ קריאות של האוסף, מותר בלי lock? כי למיטב הבנתי הנעילה גם על קריאה וגם על פעולות אחרות נועדה כדי שלא תבצע foreach ובאמצע ת'רד אחר ימחק איבר.
 
למעלה