@synchronized () ทำอะไรเป็นวิธีเดี่ยวในวัตถุประสงค์ C


88

ฉันเพิ่งสร้างวิธีการแบบซิงเกิลตันและฉันต้องการทราบว่าฟังก์ชัน@synchronized()นี้ทำหน้าที่อะไรเนื่องจากฉันใช้บ่อย แต่ไม่รู้ความหมาย

คำตอบ:


119

มันประกาศส่วนสำคัญรอบ ๆ บล็อกโค้ด ในโค้ดมัลติเธรด@synchronizedรับประกันว่าเธรดเดียวเท่านั้นที่สามารถรันโค้ดนั้นในบล็อกได้ตลอดเวลา

หากคุณไม่ทราบว่ามันทำอะไรแสดงว่าแอปพลิเคชันของคุณอาจไม่ใช่แบบมัลติเธรดและคุณอาจไม่จำเป็นต้องใช้มัน (โดยเฉพาะอย่างยิ่งหากซิงเกิลตันนั้นไม่ปลอดภัยต่อเธรด)


แก้ไข: การเพิ่มข้อมูลเพิ่มเติมบางส่วนที่ไม่ได้อยู่ในคำตอบเดิมจากปี 2554

@synchronizedสั่งป้องกันไม่ให้หลายหัวข้อจากการเข้าสู่ภูมิภาคใด ๆ ของรหัสที่ได้รับการคุ้มครองโดย@synchronizedสั่งหมายถึงวัตถุเดียวกัน วัตถุที่ส่งผ่านไปยัง@synchronizedคำสั่งคือวัตถุที่ใช้เป็น "ตัวล็อก" เธรดสองเธรดสามารถอยู่ในขอบเขตที่มีการป้องกันเดียวกันได้หากใช้อ็อบเจ็กต์อื่นเป็นตัวล็อกและคุณยังสามารถป้องกันโค้ดสองภูมิภาคที่แตกต่างกันโดยสิ้นเชิงโดยใช้อ็อบเจ็กต์เดียวกันกับล็อก

นอกจากนี้หากคุณบังเอิญผ่านnilเป็นวัตถุล็อคจะไม่มีการล็อคเลย


14
ประเด็นสำคัญสองประการ: 1) หากคุณใช้ตัวชี้ศูนย์ใน@synchronizedนั้นจะไม่ทำอะไรเลยคุณจะไม่ได้รับการป้องกัน 2) @synchronizedเป็นช้า
Hot Licks

คำตอบนี้ทำให้เข้าใจผิดและไม่ควรเป็นคำตอบที่ยอมรับได้ แม้ว่าบางครั้งสิ่งที่กล่าวจะถูกต้อง (ตราบใดที่โทเค็นที่ส่งไปยังซิงโครไนซ์เป็นวัตถุเดียวกันในทุกเธรด) แต่ก็ไม่สมบูรณ์ทำให้เข้าใจผิด ซิงโครไนซ์จะป้องกันไม่ให้ส่วนของโค้ดที่เกี่ยวข้องจำนวนมากทำงานพร้อมกันไม่ใช่แค่ "โค้ดนั้นในบล็อก" พารามิเตอร์ที่จะซิงโครไนซ์อย่างมีประสิทธิภาพจะกำหนดส่วนของโค้ด (หรือ "บล็อก" ตามที่คำตอบเรียกใช้) ได้รับการป้องกันจากการเข้าถึงพร้อมกัน
Arda

@ คุณอาร์ดาคุณพูดถูกทั้งหมด ฉันได้เพิ่มบิตข้อมูลเพิ่มเติมเล็ก ๆ น้อย ๆ @synchronizedและเชื่อมโยงไปบางส่วนเอกสารเกี่ยวกับแอปเปิ้ล
John Calsbeek

@JohnCalsbeek ตอนนี้คำตอบดูดีขึ้นมาก ยกนิ้วให้จากฉัน
Arda

@HotLicks น่าสนใจที่จะชี้ให้เห็น แต่จะดีกว่าถ้าพูดสั้น ๆ ว่าอะไรเป็นทางเลือกอื่น (ลิงค์?)
itMaxence

43

จากเอกสารของ Apple ที่นี่และที่นี่ :

คำสั่ง @synchronized เป็นวิธีที่สะดวกในการสร้างล็อค mutex ได้ทันทีในรหัส Objective-C คำสั่ง @synchronized ทำในสิ่งที่การล็อค mutex อื่น ๆ จะทำ - ป้องกันไม่ให้เธรดต่างๆได้รับการล็อกเดียวกันในเวลาเดียวกัน

เอกสารประกอบให้ข้อมูลมากมายเกี่ยวกับเรื่องนี้ มันคุ้มค่าที่จะสละเวลาอ่านโดยเฉพาะอย่างยิ่งเมื่อคุณใช้มันโดยไม่รู้ว่ามันทำอะไร


27

@synchronizedสั่งเป็นวิธีที่สะดวกในการสร้างล็อค mutex ในการบินในObjective-Cรหัส

@synchronizedสั่งไม่สิ่งใด ๆ ล็อค mutex อื่น ๆ จะทำมันป้องกันไม่ให้หัวข้อที่แตกต่างจากการแสวงหาล็อคเดียวกันในเวลาเดียวกัน

ไวยากรณ์:

 @synchronized(key) 
 { 
  // thread-safe code 
 }

ตัวอย่าง:

 -(void)AppendExisting:(NSString*)val
{
  @synchronized (oldValue) {
      [oldValue stringByAppendingFormat:@"-%@",val];
  }
}

ตอนนี้รหัสด้านบนปลอดภัยเธรดอย่างสมบูรณ์ตอนนี้หลายเธรดสามารถเปลี่ยนค่าได้

ข้างต้นเป็นเพียงตัวอย่างที่คลุมเครือ ...


3
ไม่ควรเป็น @synchronized (oldValue) ใช่หรือไม่
Joel

หรือแม้แต่@synchronized(val, oldValue) { ... }?
Valentin Shergin

ฉันไม่แน่ใจว่าฉันเคยเห็นโครงการใดที่ "ร้อยไหมปลอดภัย" อย่างน้อยที่สุดคุณต้องรู้ว่าคุณกำลังทำอะไรและไม่ใช่แค่คัดลอกโค้ดจากที่ไหนสักแห่งแบบสุ่มสี่สุ่มห้า
Hot Licks

แต่ฉันคิดว่าโค้ดด้านบนคือ "เธรดที่สมบูรณ์แบบปลอดภัย" เนื่องจากไม่มีอะไรแน่นอน
Hot Licks

6

@synchronized บล็อกจับโดยอัตโนมัติล็อกและปลดล็อกสำหรับคุณ @ ซิงโครไนซ์คุณมีการล็อกโดยนัยที่เชื่อมโยงกับวัตถุที่คุณใช้ในการซิงโครไนซ์ นี่คือการสนทนาที่ให้ข้อมูลเกี่ยวกับหัวข้อนี้โปรดติดตาม@synchronized lock / unlock ใน Objective-C อย่างไร?



-2

@synchronizedเป็นthread safeกลไก ชิ้นส่วนของโค้ดที่เขียนภายในฟังก์ชันนี้จะกลายเป็นส่วนหนึ่งcritical sectionซึ่งสามารถดำเนินการได้ทีละเธรดเท่านั้น

@synchronizeใช้การล็อกโดยปริยายในขณะที่NSLockใช้อย่างชัดเจน

รับประกันความปลอดภัยของด้ายเท่านั้นไม่รับประกันว่า สิ่งที่ฉันหมายถึงคือคุณจ้างคนขับผู้เชี่ยวชาญสำหรับรถของคุณ แต่ก็ยังไม่รับประกันว่ารถจะไม่ประสบอุบัติเหตุ อย่างไรก็ตามความน่าจะเป็นยังคงน้อยที่สุด


2
นี่เป็นสิ่งที่ผิดอย่างยิ่ง dispatch_once ไม่ทำเช่นเดียวกับ @syncrhonized แต่สามารถใช้แทนได้ภายใต้การจัดสรรซิงเกิลตันเท่านั้น
jugutier
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.