Hey all, Tôi đang làm việc trên một số mã tôi thừa hưởng, có vẻ như một sợi được thiết lập một biến thành viên boolean trong khi thread khác trong một vòng lặp while kiểm tra nó. Điều này thực sự làm việc OK hay tôi nên thay đổi nó để sử dụng đồng bộ getters hoặc setters trên boolean var?Cần đồng bộ hóa cài đặt của các thành viên boolean?
Trả lời
Trong trường hợp đọc và viết một nguyên thủy như bool hoặc int tuyên bố họ là dễ bay hơi sẽ rất nhiều. Khi một chủ đề đọc chủ đề khác sẽ hoàn thành việc viết. Biến sẽ không bao giờ ở trạng thái không hợp lệ.
Có thể công bằng khi nói rằng trên toàn bộ, từ khóa dễ bay hơi trong Java kém tài liệu, ít được hiểu và hiếm khi được sử dụng. Để làm cho vấn đề tồi tệ hơn, định nghĩa chính thức của nó thực sự thay đổi theo Java 5. Về cơ bản, biến động được sử dụng để chỉ ra rằng giá trị của biến sẽ được sửa đổi bởi các luồng khác nhau.
Khai báo một biến Java dễ bay hơi có nghĩa là:
- Giá trị của biến này sẽ không bao giờ được cache thread-địa phương: tất cả đọc và viết sẽ đi thẳng đến "bộ nhớ chính";
- Truy cập vào biến hoạt động như mặc dù nó được đính kèm trong khối đồng bộ , được đồng bộ hóa trên chính nó.
Chúng ta nói "hành vi như thể" trong điểm thứ hai, bởi vì để các lập trình viên ít nhất (và có lẽ trong hầu hết các trường JVM) không có đối tượng khóa thực tế có liên quan.
http://www.javamex.com/tutorials/synchronization_volatile.shtml
'volatile' được xác định chính xác trong thông số JLS và JVM. Tuy nhiên, nó dường như được sử dụng thường xuyên hơn nhiều so với hậu quả được hiểu. –
@Tom Hawtin - Người ta cần hiểu những hạn chế. Nó là một công cụ mạnh mẽ trong một số tình huống giới hạn. –
Trong khi những gì bạn nói là đúng của boolean (và trong một số trường hợp int) nguyên thủy, hãy cẩn thận với int khi thực hiện các hoạt động như int ++. Trong khi điều này dường như là một hoạt động duy nhất, nó không thực sự và chỉ sử dụng dễ bay hơi trong một trường hợp như thế này là không đủ. –
Hầu như chắc chắn bạn sẽ cần phải thêm khóa ở mức cao hơn. Chỉ cần thêm synchronized
xung quanh việc truy cập một lần vào các trường hiếm khi hữu ích. Các thao tác tổng hợp sẽ không an toàn chỉ khi các hoạt động thành phần độc lập với luồng an toàn.
Ví dụ: xem xét xóa nội dung của tài liệu an toàn chỉ. Tài liệu này cung cấp hai thao tác an toàn chủ đề có liên quan: xóa nội dung giữa hai chỉ mục và hoạt động chiều dài. Vì vậy, bạn có được chiều dài và xóa từ số không đến độ dài, phải không? Vâng, có một cuộc đua vì tài liệu có thể thay đổi độ dài giữa việc đọc độ dài và xóa nội dung. Không có cách nào để làm cho thread hoạt động an toàn cho các hoạt động. (Ví dụ lấy từ Swing Text.)
+1 điểm tốt để thêm một số quan điểm để xem xét nhiều hơn chỉ là biến boolean. –
Điểm của bạn được thực hiện tốt nhưng không có ngữ cảnh, dựa trên câu hỏi được hỏi, để giới thiệu đối số tổng hợp. Câu hỏi đặt ra là về vấn đề người đọc/người viết boolean. Showboating? – bjg
@bjg Threading liên quan đến ngữ cảnh. Nó vốn không phải là địa phương. Tôi tin rằng có khả năng là vấn đề trong tay đi xa hơn một boolean. Chắc chắn nó sẽ không có ích cho ai đó mới đến khu vực để giải quyết một vấn đề đặc biệt với mã khó hiểu. –
tôi sẽ đề nghị rằng boolean được khai báo biến động và đọc và viết truy cập được đồng bộ
Điều đó nghe có vẻ bối rối. (Ngoài ra 'volatile' là đáng ngạc nhiên không hữu ích (excapt ở mức thấp) vì các hoạt động thường đòi hỏi nhiều hoạt động thành phần.) –
@tackline Bạn có nghĩa là nó bị nhầm lẫn bởi vì nó là một vành đai và niềng răng tiếp cận? Nếu có, thì trong khi tôi hiểu mô hình lập trình Java có thể cho rằng dễ bay hơi thì tôi vẫn nghi ngờ về yêu cầu này đối với tất cả các triển khai JVM mà tôi có thể gặp phải khi chạy trên các môi trường muti-core. Trong mọi trường hợp - ngay cả khi hoang tưởng của tôi không bị phát hiện - dễ bay hơi thì thường không phải là một gợi ý đủ mạnh cho những người bảo trì rằng có điều gì đó quan trọng mà họ cần phải biết về mối quan hệ với boolean trong câu hỏi – bjg
Bạn nên khai báo một biến 'volatile' hoặc sử dụng accessors' sync'. Làm cả hai chỉ cản trở hiệu suất và tăng thêm độ phức tạp. Và Tom nói đúng rằng việc sử dụng chính xác của dễ bay hơi chủ yếu được dành riêng bởi các chuyên gia java.concurrent. –
Nếu bạn sử dụng java 1.5+, Bạn nên sử dụng Condition đồng bộ hóa ban.
Nếu bạn theo liên kết, nó có ví dụ hay về cách sử dụng.
Nó không được bảo đảm để làm việc nếu đó là một boolean đơn giản, một trong những chủ đề không thể thấy boolean được cập nhật do mô hình ký ức về java, bạn có thể
- tạo ra một getter đồng bộ/setter hoặc
- tuyên bố boolean là dễ bay hơi, http://www.ibm.com/developerworks/java/library/j-jtp06197.html là một nguồn tài nguyên tốt cho understaning dễ bay hơi.
Hãy nhớ rằng không có cách nào trong số này có thể "hoạt động" nếu luồng đọc boolean này phụ thuộc vào giá trị trước đó của boolean - nó có thể bỏ lỡ các thay đổi đối với boolean đó, ví dụ:
thread1:
while(foo.myVolatileBoolean) {
...
}
thread2:
foo.myVolatileBoolean = false; //thread 1 might never catch thisone.
...
foo.myVolatileBoolean = true;
Nếu đây là một vấn đề và bạn cần phải theo dõi thay đổi đối với boolean, xem xét sử dụng wait()/thông báo() hoặc Condition
- 1. cài đặt đồng bộ hóa không gian làm việc eclipse - những gì cần đồng bộ hóa?
- 2. cài đặt đồng bộ hóa chung "tự động đồng bộ hóa" hộp kiểm lập trình
- 3. Android - Cài đặt đồng bộ hóa tài khoản Google
- 4. đồng bộ hóa các tệp mà không cần cam kết?
- 5. Có cách nào để đồng bộ hóa cài đặt từ Cài đặt.StyleCop sang ReSharper không?
- 6. Cài đặt đồng bộ hóa giữa các máy tính trong Visual Studio 2010
- 7. Làm cách nào để đồng bộ hóa cài đặt Chia sẻ lại giữa các máy tính?
- 8. iOS5.1: đồng bộ hóa các tác vụ (chờ hoàn thành)
- 9. Làm thế nào để đồng bộ hóa các gói và cài đặt Emacs?
- 10. Đơn đặt hàng được đồng bộ hóa
- 11. Cần đồng bộ hóa cho bộ đếm chỉ tăng?
- 12. Các công cụ đồng bộ hóa cơ sở dữ liệu khác ngoài Khung Đồng bộ hóa của Microsoft?
- 13. Sự kiện đồng bộ hóa đặt lại xương sống 1.0 và sự kiện đồng bộ hóa
- 14. đồng bộ hóa (this) vs đồng bộ hóa (MyClass.class)
- 15. Java: Có phải tất cả các phương thức tĩnh cần được đồng bộ hóa không?
- 16. Đồng bộ hóa vai trò của Azure
- 17. Làm cách nào để cập nhật các thành viên của một Loại Cài đặt MySQL?
- 18. Java: Đồng bộ hóa một ExecutorService cần thiết?
- 19. iTunes Đồng bộ hóa "MyAppName" Không thể cài đặt- Tệp IPA
- 20. Làm cách nào để cài đặt MSI đồng bộ?
- 21. Hiển thị cài đặt trong trình đơn tài khoản & đồng bộ hóa cho ứng dụng android
- 22. Các chuỗi Java "đã đồng bộ hóa"
- 23. Đồng bộ hóa cuộc gọi không đồng bộ trong C#
- 24. Sử dụng hợp lệ hàm thành viên tĩnh của lớp mà không thể được cài đặt
- 25. đồng bộ hóa các chủ đề java
- 26. Mẫu thiết kế đồng bộ hóa đồng bộ hóa tối ưu hóa
- 27. Làm thế nào để đồng bộ hóa người quản lý/nhân viên pthreads mà không cần tham gia?
- 28. biến cục bộ của các hàm thành viên tĩnh
- 29. Semaphore và đồng bộ hóa
- 30. Thành viên của Bản sao thành viên
Câu trả lời hay cho đến nay các bạn, tôi đã nghĩ rằng vòng lặp while có thể là bộ nhớ đệm biến mà nó đang cố gắng kiểm tra cục bộ. Tôi đang thêm volatile bây giờ và đặt biến trong một getter đồng bộ và setter. –
Tôi nghĩ rằng bạn đã không đọc các câu trả lời (và tài liệu) đúng cách, đặc biệt là một từ Tom Hawtin. Đồng bộ hóa truy cập vào một biến dễ bay hơi là một oxymoron. –
Tôi đồng ý dễ bay hơi sẽ bảo vệ biến boolean của bạn và chắc chắn rằng nó đang được cập nhật và đọc đúng cách, nhưng bạn cần phải nhìn vào bức tranh lớn và chắc chắn rằng đối tượng của bạn luôn ở trạng thái nhất quán. –