Bất cứ khi nào một câu hỏi xuất hiện trên SO về đồng bộ hóa Java, một số người rất muốn chỉ ra rằng synchronized(this)
nên tránh. Thay vào đó, họ tuyên bố, một khóa trên một tài liệu tham khảo riêng tư sẽ được ưu tiên.
Một số lý do được đưa ra là:
- một số mã xấu có thể đánh cắp khóa của bạn (rất phổ biến mã này, cũng có một biến thể "vô tình")
- tất cả các phương thức được đồng bộ hóa trong cùng một lớp đều sử dụng cùng một khóa chính xác, giúp giảm thông lượng
- bạn (không cần thiết) tiết lộ quá nhiều thông tin
Những người khác, bao gồm cả tôi, cho rằng đó synchronized(this)
là một thành ngữ được sử dụng rất nhiều (cũng trong các thư viện Java), là an toàn và được hiểu rõ. Không nên tránh vì bạn có lỗi và bạn không biết gì về những gì đang diễn ra trong chương trình đa luồng của mình. Nói cách khác: nếu nó được áp dụng, sau đó sử dụng nó.
Tôi thích xem một số ví dụ trong thế giới thực (không có nội dung foobar) trong đó tránh việc khóa trên this
là thích hợp hơn khi synchronized(this)
cũng sẽ thực hiện công việc.
Do đó: bạn có nên luôn luôn tránh synchronized(this)
và thay thế nó bằng một khóa trên một tài liệu tham khảo riêng tư?
Một số thông tin khác (cập nhật dưới dạng câu trả lời được đưa ra):
- chúng ta đang nói về đồng bộ hóa cá thể
- cả ẩn (
synchronized
phương thức) và hình thức rõ ràngsynchronized(this)
đều được xem xét - nếu bạn trích dẫn Bloch hoặc các cơ quan khác về chủ đề này, đừng bỏ qua những phần bạn không thích (ví dụ: Java hiệu quả, mục về An toàn chủ đề: Thông thường, đó là khóa trên chính cá thể, nhưng vẫn có ngoại lệ.)
- nếu bạn cần độ chi tiết trong khóa của bạn ngoài việc
synchronized(this)
cung cấp, thìsynchronized(this)
không thể áp dụng được nên đó không phải là vấn đề