2012-02-27 32 views
5

Tôi đang nghĩ ở đây: Nếu bạn có 2 luồng thực thi các thao tác FAST cần được đồng bộ hóa, không phải là phương pháp không chặn đứng nhanh hơn/tốt hơn phương pháp chặn/chuyển ngữ cảnh?Chặn khóa so với khóa không chặn

By non-blocking I có nghĩa là một cái gì đó như:

while (true) { if (checkAndGetTheLock()) phá vỡ; }

Điều duy nhất tôi có thể nghĩ đến là đói (với CPU bị đốt cháy) nếu bạn có quá nhiều luồng lặp xung quanh khóa.

Làm cách nào để cân bằng một phương pháp so với phương pháp kia?

+0

Bạn sẽ thực hiện bao nhiêu thao tác khóa cho mỗi lõi CPU mỗi giây? – usr

+0

AFAIK, JVM thực hiện tối ưu hóa này cho bạn nếu không có tranh chấp về khóa (trường hợp đó là nhanh) –

+0

@JB Nizet: Tôi nghĩ bạn phải tự quyết định bằng cách sử dụng đồng bộ hóa so với ReentrantLock. – chrisapotek

Trả lời

5

Đây là những gì Java Concurrency in Practice nói về chủ đề này:

Các JVM có thể thực hiện chặn hoặc thông qua spin-chờ đợi (lần cố gắng để có được khóa cho đến khi nó thành công) hoặc bysuspending các chặn luồng thông qua hệ điều hành. Đó là hiệu quả hơn phụ thuộc vào mối quan hệ giữa chi phí chuyển ngữ cảnh và thời gian cho đến khi khóa khả dụng; chờ đợi quay là thích hợp hơn đối với thời gian chờ đợi và đình chỉ ngắn là thích hợp cho thời gian chờ đợi dài. Một số JVM chọn giữa hai tùy chọn dựa trên dữ liệu lược tả của quá khứ chờ đợi lần, nhưng hầu hết chỉ tạm dừng các chủ đề đang chờ khóa.

Và cũng (đó là, IMO, điểm quan trọng nhất):

Đừng lo lắng quá nhiều về chi phí đồng bộ hóa uncontended. Cơ chế cơ bản đã khá nhanh và JVM có thể thực hiện tối ưu hóa bổ sung để giảm hoặc loại bỏ chi phí hơn nữa. Thay vào đó, hãy tập trung tối ưu hóa các nỗ lực vào các khu vực có tranh chấp khóa thực sự xảy ra.

+0

Tôi sẽ không tin tưởng rằng "Một số JVM chọn giữa hai tùy chọn dựa trên dữ liệu lược tả của thời gian chờ đợi trước đây, nhưng hầu hết chỉ tạm dừng các chủ đề đang chờ khóa". Nhưng bạn không bao giờ có thể biết những JVM hotspot hiện đại nào có khả năng. Tôi nghĩ rằng việc đồng bộ đang chặn và ReentrantLock đang chờ đợi. Nhưng nếu họ có thể thay đổi vào nhau trong thời gian chạy tôi không chắc chắn. – chrisapotek

+1

Bạn đã đọc ReentrantLock ở đâu? Nếu nó đã làm, nó sẽ mang lại cho JVM để đầu gối của mình cho chờ đợi lâu dài. Các javadoc nói: * Một khóa loại trừ lẫn nhau reentrant với cùng một hành vi cơ bản và ngữ nghĩa như khóa giám sát tiềm ẩn truy cập bằng cách sử dụng phương pháp đồng bộ và báo cáo, nhưng với khả năng mở rộng * –

+0

Tôi có thể sai, nhưng bằng cách duyệt mã nguồn tôi nghĩ rằng nó là cách tiếp cận của nó: http://fuseyism.com/classpath/doc/java/util/concurrent/locks/AbstractQueuedSynchronizer-source.html NOOOOO! JVM KHÔNG sử dụng ReentrantLock cho những thứ bên trong của nó. – chrisapotek

1

Cách duy nhất để chắc chắn là kiểm tra nó. Khi nói đến đa luồng và hiệu suất bạn chỉ đơn giản là không thể giả định.

+0

Câu trả lời này là chính xác và không nên được giảm giá. – usr

+0

@usr tốt, tại sao bạn không upvote nó sau đó? Tôi vô cùng cám dỗ để hạ thấp nó hai lần, nhưng điều đó sẽ không công bằng trên M Platvoet. –

+0

Tôi đã bỏ phiếu. Có một downvote hủy bỏ. – usr