2010-03-19 31 views
7

Câu hỏi Java 6 API. Việc gọi số LockSupport.unpark(thread) có mối quan hệ xảy ra trước khi trả lại từ LockSupport.park trong chuỗi không công bằng không? Tôi mạnh mẽ nghi ngờ câu trả lời là có, nhưng Javadoc dường như không đề cập đến nó một cách rõ ràng.Java LockSupport Memory Consistency

Trả lời

1

Tôi đã xem xét mặc dù mã JDK và có vẻ như phương pháp LockSupport thường được gọi bên ngoài khối đồng bộ hóa. Vì vậy, giả định của bạn có vẻ là chính xác.

+1

Xin lỗi để bình luận về câu trả lời cũ, nhưng vì câu hỏi là về Java * API * chứ không phải * triển khai * do Sun/Oracle cung cấp, hãy xem cách JDK sử dụng 'LockSupport' không chính xác 100%. Các nhà phát triển JDK có thể đưa ra các giả định về việc thực hiện riêng của họ, trong khi một ứng dụng di động không nên. Ngoài ra, có nhiều cách để đạt được một mối quan hệ * xảy ra trước * mà không liên quan đến bất kỳ khối 'đồng bộ' nào. – rolve

+0

"... xem qua mã JDK": Bạn có thể xin vui lòng đăng một URL hg cho OpenJDK không? – kevinarpe

5

Nếu nó không được ghi lại như vậy thì bạn KHÔNG THỂ dựa vào nó để tạo ra một sự kiện xảy ra trước mối quan hệ.

Cụ thể LockSupport.java trong mã Hotspot chỉ cần gọi Unsafe.park và .unpark!

Mối quan hệ xảy ra trước khi mối quan hệ thường đến từ một cặp ghi đọc trên cờ trạng thái dễ bay hơi hoặc điều gì đó tương tự.

Hãy nhớ rằng, nếu nó không phải là tài liệu như tạo một xảy ra-trước mối quan hệ sau đó bạn phải đối xử với nó như thể nó không thậm chí nếu bạn có thể chứng minh rằng nó trên hệ thống cụ thể của bạn. Các hệ thống và triển khai trong tương lai có thể không. Họ để lại tự do vì lý do chính đáng.

6

Tôi vừa tìm thấy câu hỏi này bởi vì tôi đã tự hỏi mình điều tương tự. Theo số this article của nhà nghiên cứu Oracle David Dice, câu trả lời có vẻ là không. Dưới đây là phần có liên quan của bài viết:

Nếu một thread bị chặn trong park() chúng tôi sẽ được bảo đảm rằng một tiếp theo unpark() sẽ làm cho nó sẵn sàng. Việc triển khai hoàn toàn hợp pháp nhưng chất lượng thấp park()unpark() sẽ là các phương thức trống, trong đó chương trình bị thoái hóa thành quay đơn giản. Thực tế, đó là thử nghiệm litmus cho chính xác park() - unpark() cách sử dụng.

Rỗng park()unpark() phương pháp này không cung cấp cho bạn bất kỳ xảy ra-trước đảm bảo mối quan hệ, vì vậy cho chương trình của bạn là 100% xách tay, bạn không nên dựa vào họ.

Sau đó, một lần nữa, Javadoc of LockSupport nói:

Những phương pháp này được thiết kế để được sử dụng như công cụ để tạo tiện ích đồng bộ cấp cao hơn, và không phải ở bản thân hữu ích đối với hầu hết các ứng dụng kiểm soát đồng thời. Phương pháp park được được thiết kế để sử dụng chỉ trong công trình xây dựng có dạng:

while (!canProceed()) { ... LockSupport.park(this); }

Vì bạn phải kiểm tra một cách rõ ràng một số điều kiện nào, mà một trong hai sẽ bao gồm volatile hay đúng biến đồng bộ, đảm bảo yếu park() không thực sự là vấn đề, phải không?

+2

Cảm ơn câu trả lời này. Bây giờ tôi không thể nhớ tại sao tôi muốn biết điều này. Tôi nghi ngờ tôi đã tự hỏi nếu khi thread chạy cập nhật điều kiện và được gọi là 'unpark', nếu đó sẽ tự bảo đảm thread unparked sẽ thấy điều kiện cập nhật trong trạng thái nhất quán. Có vẻ như không có bảo đảm, do đó, lựa chọn an toàn duy nhất là sắp xếp một rào cản bộ nhớ một cách rõ ràng để cập nhật điều kiện. – Lachlan

+0

Tôi hiểu. Nếu có một mối quan hệ * xảy ra trước * giữa 'park()' và 'unpark()', thì điều kiện sẽ không cần phải liên quan đến một rào cản bộ nhớ. Vì vậy, câu hỏi vẫn còn hợp lệ. – rolve