@Synchronized () làm gì như một phương thức singleton trong mục tiêu C?


87

Tôi vừa tạo một phương thức singleton và tôi muốn biết chức năng @synchronized()này làm gì, vì tôi sử dụng nó thường xuyên, nhưng không biết ý nghĩa.

Câu trả lời:


119

Nó khai báo một phần quan trọng xung quanh khối mã. Trong mã đa luồng, @synchronizedđảm bảo rằng chỉ một luồng có thể thực thi mã đó trong khối tại bất kỳ thời điểm nào.

Nếu bạn không biết nó làm gì, thì ứng dụng của bạn có thể không đa luồng và bạn có thể không cần sử dụng nó (đặc biệt nếu bản thân singleton không an toàn theo luồng).


Chỉnh sửa: Thêm một số thông tin khác không có trong câu trả lời ban đầu từ năm 2011.

Các @synchronizedchỉ thị ngăn chặn nhiều chủ đề từ khi vào bất kỳ vùng mã được bảo vệ bởi một @synchronizedchỉ thị đề cập đến cùng một đối tượng . Đối tượng được truyền cho @synchronizedchỉ thị là đối tượng được sử dụng làm "khóa". Hai luồng có thể nằm trong cùng một vùng mã được bảo vệ nếu một đối tượng khác được sử dụng làm khóa và bạn cũng có thể bảo vệ hai vùng mã hoàn toàn khác nhau bằng cách sử dụng cùng một đối tượng làm khóa.

Ngoài ra, nếu bạn tình cờ vượt qua nilvới tư cách là đối tượng khóa, sẽ không có khóa nào được thực hiện.


14
Một vài điểm quan trọng: 1) Nếu bạn sử dụng một con trỏ nil trong @synchronizednó thì không có gì - bạn không được bảo vệ. 2) @synchronizedchậm .
Hot Licks, 27/07/13

Câu trả lời này gây hiểu lầm và không nên là câu trả lời được chấp nhận. Mặc dù những gì nó nói đôi khi sẽ đúng (miễn là mã thông báo được chuyển đến đồng bộ hóa là cùng một đối tượng trong tất cả các chuỗi), nhưng nó không đầy đủ một cách gây hiểu lầm. đồng bộ hóa ngăn không cho bất kỳ số phần mã liên quan nào thực thi cùng một lúc, không chỉ "mã đó trong khối". Tham số được đồng bộ hóa một cách hiệu quả xác định phần mã nào (hoặc "khối" khi câu trả lời gọi chúng) được bảo vệ khỏi truy cập đồng thời.
Arda

@Arda Bạn hoàn toàn đúng. Tôi đã thêm một chút thông tin và liên kết đến một số tài liệu của Apple về @synchronized.
John Calsbeek

@JohnCalsbeek, câu trả lời hiện có vẻ tốt hơn nhiều. Thích từ tôi.
Arda

@HotLicks thú vị khi chỉ ra điều này, nhưng thậm chí còn tốt hơn nếu nói ngắn gọn đâu có thể là các lựa chọn thay thế (liên kết?)
itMaxence

43

Từ tài liệu của Apple tại đâyđây :

Chỉ thị @synchronized là một cách thuận tiện để tạo khóa mutex nhanh chóng trong mã Objective-C. Lệnh @synchronized thực hiện những gì mà bất kỳ khóa mutex nào khác sẽ làm — nó ngăn các luồng khác nhau có được cùng một khóa cùng một lúc.

Tài liệu cung cấp nhiều thông tin về chủ đề này. Bạn nên dành thời gian để đọc qua nó, đặc biệt là khi bạn đang sử dụng nó mà không biết nó đang làm gì.


26

Lệnh @synchronizedlà một cách thuận tiện để tạo khóa mutex một cách nhanh chóng trong mã Objective-C .

Lệnh @synchronizednày thực hiện những gì mà bất kỳ khóa mutex nào khác sẽ làm — nó ngăn các luồng khác nhau có được cùng một khóa cùng một lúc.

Cú pháp:

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

Thí dụ:

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

Bây giờ mã trên hoàn toàn an toàn cho chủ đề..Bây giờ nhiều luồng có thể thay đổi giá trị.

Trên đây chỉ là một ví dụ khó hiểu ...


3
Nó không phải là @synchronized (oldValue)?
Joel

Hoặc thậm chí @synchronized(val, oldValue) { ... }?
Valentin Shergin

Tôi không chắc mình đã từng thấy bất kỳ kế hoạch nào "hoàn toàn an toàn cho chuỗi". Ít nhất bạn cần biết mình đang làm gì và không chỉ sao chép mã từ đâu đó một cách mù quáng.
Hot Licks

Nhưng tôi cho rằng đoạn mã trên là "hoàn toàn an toàn trong chuỗi", vì nó hoàn toàn không có tác dụng gì.
Hot Licks



-2

@synchronizedthread safecơ chế. Đoạn mã được viết bên trong hàm này trở thành một phần của critical sectionnó mà chỉ một luồng có thể thực thi tại một thời điểm.

@synchronizeáp dụng khóa một cách ngầm trong khi NSLockáp dụng nó một cách rõ ràng.

Nó chỉ đảm bảo an toàn cho chủ đề, không đảm bảo điều đó. Ý tôi là bạn thuê một tài xế chuyên nghiệp cho chiếc xe của bạn, điều đó vẫn không đảm bảo rằng chiếc xe sẽ không gặp tai nạn. Tuy nhiên xác suất vẫn là nhỏ nhất.


2
Điều này là hoàn toàn sai lầm. Dispatch_once KHÔNG làm tương tự như @syncrhonized, nó chỉ có thể thay thế khi phân bổ một singleton.
jugutier
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.