Sự cố bạn gặp phải là bạn không đợi đủ lâu để mã được tối ưu hóa và giá trị được lưu vào bộ nhớ cache.
Khi chuỗi trên hệ thống x86_64 lần đọc giá trị lần đầu tiên, nó sẽ nhận được bản sao an toàn chủ đề. Chỉ những thay đổi sau này của nó mới có thể không nhìn thấy được. Điều này có thể không phải là trường hợp trên các CPU khác.
Nếu bạn thử điều này, bạn có thể thấy rằng mỗi luồng bị mắc kẹt với giá trị cục bộ của nó.
public class RequiresVolatileMain {
static volatile boolean value;
public static void main(String... args) {
new Thread(new MyRunnable(true), "Sets true").start();
new Thread(new MyRunnable(false), "Sets false").start();
}
private static class MyRunnable implements Runnable {
private final boolean target;
private MyRunnable(boolean target) {
this.target = target;
}
@Override
public void run() {
int count = 0;
boolean logged = false;
while (true) {
if (value != target) {
value = target;
count = 0;
if (!logged)
System.out.println(Thread.currentThread().getName() + ": reset value=" + value);
} else if (++count % 1000000000 == 0) {
System.out.println(Thread.currentThread().getName() + ": value=" + value + " target=" + target);
logged = true;
}
}
}
}
}
in dưới đây cho thấy giá trị lật của nó, nhưng bị kẹt.
Sets true: reset value=true
Sets false: reset value=false
...
Sets true: reset value=true
Sets false: reset value=false
Sets true: value=false target=true
Sets false: value=true target=false
....
Sets true: value=false target=true
Sets false: value=true target=false
Nếu tôi thêm -XX:+PrintCompilation
chuyển đổi này xảy ra khoảng thời gian mà bạn nhìn thấy
1705 1 % RequiresVolatileMain$MyRunnable::run @ -2 (129 bytes) made not entrant
1705 2 % RequiresVolatileMain$MyRunnable::run @ 4 (129 bytes)
Những gợi ý mã đã được biên soạn để có nguồn gốc là một cách mà không phải là thread an toàn.
nếu bạn làm cho giá trị volatile
bạn nhìn thấy nó lật giá trị vô tận (hoặc cho đến khi tôi đã chán)
EDIT: Điều gì kiểm tra này không có gì; khi nó phát hiện giá trị không phải là giá trị mục tiêu của chủ đề, nó đặt giá trị. I E. chuỗi 0 đặt thành true
và chuỗi 1 đặt thành false
Khi hai chuỗi đang chia sẻ trường đúng cách, chúng sẽ thấy mỗi thay đổi khác và giá trị liên tục lật giữa giá trị đúng và sai.
Không có biến động này không thành công và mỗi chuỗi chỉ thấy giá trị riêng của chúng, do đó cả hai đều thay đổi giá trị và chuỗi 0 xem true
và chuỗi 1 xem false
cho cùng một trường.
Câu trả lời ngắn không. Nhưng bạn có thực sự cần phải kiểm tra xem nhảy từ mái nhà là nguy hiểm sau khi ai đó nói với bạn và đưa ra lý do tốt? – Voo
Sử dụng máy tính có 2 lõi. –
@Voo ... bạn đang nói cái quái gì vậy? –