2012-01-30 32 views

Trả lời

0

Tôi luôn nghĩ đến việc đồng bộ hóa là "bản hack ít nhất kháng cự". Nó chỉ hoạt động và hầu hết mọi người hiểu cách nó hoạt động, nhưng nó có một số điểm yếu có thể ảnh hưởng đến thiết kế của bạn dưới sự tương tranh nặng. Không ít nhất trong số đó là bất kỳ khách hàng có hiệu quả có quyền truy cập trực tiếp vào khóa đồng bộ hóa của đối tượng của bạn có nghĩa là nếu họ lấy nó và giữ nó khách hàng khác có thể không. Nói cách khác, khóa được thực hiện bằng đồng bộ hóa mặc định có hiệu quả "xuất bản" cơ chế khóa nội bộ của đối tượng của bạn. Yuk. Nó giống như thiết lập chính mình cho tự chối từ chối dịch vụ.

Nếu bạn đặt khóa reentrant bên trong lớp học của bạn (hoặc không sử dụng đồng bộ hóa nhưng thực hiện điều gì đó như đồng bộ hóa trên một số đối tượng bên trong mà bạn mới tạo ra ở bất kỳ nơi nào bạn muốn đồng bộ hóa), bạn loại bỏ mặt này -Hiệu quả của việc xuất bản cơ chế khóa nội bộ của bạn, với sự phức tạp thêm của bạn phải nhớ nơi áp dụng đồng bộ hóa nội bộ này khi lớp của bạn phát triển.

+0

"bất kỳ khách hàng nào có quyền truy cập trực tiếp vào khóa đồng bộ hóa đối tượng của bạn" chỉ khi bạn áp dụng công cụ sửa đổi 'đồng bộ hóa 'thành phương pháp có thể truy cập, chứ không phải nếu bạn sử dụng khối' đồng bộ' trên đối tượng khóa không thể truy cập. – Raedwald

+0

Vâng. Đó là những gì tôi nói. Nếu bạn sử dụng từ khóa được đồng bộ hóa mặc định trên các phương pháp của mình, bạn sẽ xuất bản khóa của mình một cách hiệu quả. Để giải quyết vấn đề này, hãy tạo khối nội bộ được đồng bộ hóa. –

21

Một ReentrantLock là:

Một reentrant loại trừ lẫn nhau Lock với hành vi cơ bản giống nhau và ngữ nghĩa như khóa màn hình ngầm truy cập sử dụng đồng bộ phương pháp và tuyên bố, nhưng với khả năng mở rộng.

khả năng mở rộng bao gồm:

  1. Khả năng có nhiều hơn một condition variable mỗi màn hình. Màn hình sử dụng từ khóa được đồng bộ hóa chỉ có thể có một. Điều này có nghĩa là các khóa reentrant hỗ trợ nhiều hơn một hàng chờ đợi()/notify().
  2. Khả năng khóa fair. Các khối được đồng bộ hóa là không công bằng.

    "khóa [công bằng] ưu tiên cấp quyền truy cập vào chuỗi dài nhất đang đợi. Nếu không khóa này không đảm bảo bất kỳ thứ tự truy cập cụ thể nào."

  3. Khả năng kiểm tra xem khóa có được giữ hay không.
  4. Khả năng nhận danh sách các chuỗi đang chờ trên khóa.

Các nhược điểm của ổ khóa reentrant là:

  1. Cần thêm tuyên bố nhập khẩu.
  2. Cần bọc các vụ mua khóa trong khối thử/cuối cùng. Điều này làm cho nó xấu hơn từ khóa được đồng bộ hóa.
  3. Từ khóa synchronized có thể được đặt trong các định nghĩa phương thức tránh được sự cần thiết của một khối làm giảm lồng nhau.

Tóm tắt

Từ khóa synchronized là cú pháp đẹp hơn, nhưng các khóa reentrant có nhiều tính năng hơn.

0

Trang web này đã đề cập rõ ràng sự khác biệt giữa ReentrantLock và từ khóa được đồng bộ hóa trong Java. Tôi chỉ cần sao chép và dán từ đó.

http://javarevisited.blogspot.in/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html

1) Một khác biệt đáng kể giữa ReentrantLock và từ khóa synchronized là sự công bằng. từ khóa được đồng bộ hóa không hỗ trợ tính công bằng. Bất kỳ chủ đề nào cũng có thể lấy khóa khi được phát hành, không có sự ưu tiên nào có thể được chỉ định, mặt khác bạn có thể làm cho ReentrantLock công bằng bằng cách xác định tính công bằng, trong khi tạo ra thể hiện của ReentrantLock. Tài sản công bằng cung cấp khóa cho chuỗi chờ đợi dài nhất, trong trường hợp tranh chấp.

2) Sự khác biệt thứ hai giữa khóa đồng bộ và khóa Reentrant là phương thức tryLock(). ReentrantLock cung cấp phương thức tryLock() thuận tiện, chỉ mua khóa nếu nó có sẵn hoặc không được giữ bởi bất kỳ chủ đề nào khác. Điều này làm giảm chặn luồng chờ khóa trong ứng dụng Java.

3) Một sự khác biệt đáng chú ý đáng chú ý hơn giữa ReentrantLock và từ khóa được đồng bộ hóa trong Java là khả năng ngắt Thread trong khi đợi khóa. Trong trường hợp từ khóa được đồng bộ hóa, một chuỗi có thể bị chặn chờ khóa, trong một khoảng thời gian không xác định và không có cách nào để kiểm soát điều đó. ReentrantLock cung cấp một phương thức gọi là lockInterruptibly(), có thể được sử dụng để ngắt thread khi nó đang chờ khóa. Tương tự tryLock() với thời gian chờ có thể được sử dụng để hết giờ nếu khóa không có sẵn trong một khoảng thời gian nhất định.

4) ReentrantLock cũng cung cấp phương thức tiện lợi để có được Danh sách tất cả các chuỗi đang chờ khóa.

Các vấn đề liên quan