Tôi đã có một chủ đề Java làm điều gì đó như thế này:Java chủ đề một cách tự nhiên thức dậy
while (running) {
synchronized (lock) {
if (nextVal == null) {
try {
lock.wait();
} catch (InterruptedException ie) {
continue;
}
}
val = nextVal;
nextVal = null;
}
...do stuff with 'val'...
}
Ở những nơi khác tôi thiết lập giá trị như thế này:
if (val == null) {
LOG.error("null value");
} else {
synchronized (lock) {
nextVal = newVal;
lock.notify();
}
}
thoảng (theo nghĩa đen một lần mỗi vài triệu times) nextVal sẽ được đặt thành null. Tôi đã ném trong các tin nhắn đăng nhập và tôi có thể thấy rằng tự thực hiện như sau:
- thread1 đặt NEXTVAL để newVal
- thread1 gọi lock.notify()
- thread2 tỉnh dậy từ khóa. chờ()
- thread2 đặt val để NEXTVAL
- thread2 đặt NEXTVAL null
- thread2 hiện công cụ với val
- thread2 gọi lock.wait()
- thread2 tỉnh dậy từ lock.wait()
- không có thread khác đã kêu gọi lock.notify() và thread2 đã không bị gián đoạn
- thread2 đặt val để NEXTVAL (đó là null)
- v.v.
Tôi đã kiểm tra rõ ràng và khóa đang thức dậy lần thứ hai, nó không bị gián đoạn.
Tôi có làm gì sai ở đây không?
+1 cho lời giải thích rõ ràng, nhưng -1 vì không đọc Javadoc cẩn thận hơn :-) –
IIRC, không đảm bảo rằng chuỗi sẽ không đánh thức khi chờ trong khi điều kiện chờ vẫn không hài lòng. Bạn phải luôn luôn kiểm tra điều kiện và thực hiện lại sự chờ đợi nếu không hài lòng. –
(Lý do cho việc này liên quan đến sự phức tạp của việc thực hiện logic "đánh thức". Đảm bảo rằng không bao giờ có một lần đánh thức giả mạo là không thể nếu không có nhiều đồng bộ hóa đắt tiền.) –