EDIT: Tôi giả sử bạn có nghĩa là Queue<Object> objectList
thay vì ConcurrentLinkedQueue<Object> objectList
. ConcurrentLinkedQueue<Object>
đã thực hiện tất cả các chủ đề an toàn cho bạn, nghĩa là bạn có thể gọi objectList.peek()
tất cả những gì bạn muốn mà không phải lo lắng về điều kiện chủng tộc. Điều này là tuyệt vời nếu bạn đang phát triển các chương trình đa luồng nhưng không quá tuyệt vời cho việc học về an toàn luồng.
Phương pháp của bạn không cần phải là synchronized
, giả sử bạn có một chuỗi hoạt động trên một cá thể của đối tượng tại một thời điểm, tuy nhiên nếu bạn cần có nhiều phiên bản của tất cả tham chiếu đến cùng một biến lớp tĩnh, bạn cần phải synchronized
qua biến lớp học như vậy:
public static void getHeadObject() {
synchronized(safe.objectList) {
System.out.println(objectList.peek().toString());
}
}
này khóa objectList
và không cho phép nó để được đọc hoặc ghi vào trong bất kỳ chủ đề khác ngay sau khi chương trình là bên trong khối đồng bộ hóa. Làm tương tự cho tất cả các phương thức khác là synchronized
.
LƯU Ý:
Tuy nhiên, kể từ khi bạn đang làm chỉ có một đơn giản get hoạt động List.peek()
, bạn thực sự không cần phải đồng bộ hóa qua objectList
vì trong một điều kiện chủng tộc, nó sẽ nhận được một trong hai giá trị List
hoặc cách khác. Vấn đề với điều kiện chủng tộc là khi nhiều hoạt động đọc/ghi phức tạp được thực hiện, với giá trị thay đổi ở giữa chúng.
Ví dụ, nếu bạn đã có một lớp PairInt
với một PairInt.x
và PairInt.y
lĩnh vực, với ràng buộc là x = 2y
, và bạn muốn làm
System.out.println(myIntPair.x.toString() + ", " + myIntPair.y.toString());
và thread khác đã được cập nhật các giá trị của x
và y
tại cùng một lúc,
myIntPair.y = y + 3;
myIntPair.x = 2 * y;
Và chủ đề đã chỉnh sửa myIntPair
ở giữa chủ đề đã đọc myIntPair.x.toString()
và myIntPair.y.toString()
bạn có thể nhận được đầu ra trông giống như (10, 8)
, có nghĩa là nếu bạn đang hoạt động với giả định rằng x == 2 * y
có thể làm hỏng chương trình của bạn.
Trong trường hợp đó, đọc của bạn cần phải sử dụng một synchronized
, nhưng đối với những thứ đơn giản hơn như peek()
trên một đơn giản object
đang được thêm vào hoặc xóa, không thay đổi trong khi trong hàng đợi, các synchronized
thể, trong hầu hết các trường hợp Bị bỏ. Thực tế, đối với string
, int
, bool
và các loại tương tự, điều kiện synchronized
để đọc đơn giản sẽ bị xóa.
Tuy nhiên, việc viết phải luôn là synchronized
về các hoạt động không rõ ràng là an toàn, tức là đã được java xử lý. Và ngay khi bạn có được nhiều hơn một tài nguyên, hoặc yêu cầu tài nguyên của bạn giữ nguyên trong suốt hoạt động như bạn làm nhiều dòng logic để nó, sau đó bạn PHẢI SỬ DỤNGsynchronized
Tại sao 'addObject' một phương pháp dụ? Tại sao không tĩnh? Tại sao bạn đồng bộ hóa xung quanh một đối tượng đồng thời? Chúng đã được an toàn. – Wug
Bạn có ý nghĩa gì bởi trạng thái không nhất quán? –
Tôi giả định anh ta có nghĩa là 'Queue