Gần đây tôi đã tranh cãi với một người bạn trên một mã như thế này:Tầm nhìn của gán để biến trong Java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* See memory consistency effects in a Java Executor.
*/
public class PrivateFieldInEnclosing {
private long value;
PrivateFieldInEnclosing() {}
void execute() {
value = initializeValue();
ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(new Y());
}
class Y implements Runnable {
@Override
public void run() {
System.out.println(value);
}
}
private long initializeValue() {
return 20;
}
public static void main(String[] args) {
new PrivateFieldInEnclosing().execute();
}
}
Tôi cho rằng nó có thể là value
thể được xem như 0
trong Y
, bởi vì không có đảm bảo rằng bài tập value = initializeValue()
hiển thị trong chuỗi của người thi hành. Tôi nói anh ta cần phải làm cho value
một trường dễ bay hơi.
Anh ta mâu thuẫn với tôi, và nói rằng vì đó là một trường cá thể riêng với giá trị được gán trước khi tạo chuỗi, khi đó giá trị sẽ hiển thị.
Tôi đã xem xét https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4 nhưng tôi không thể đặt ngón tay của mình lên chính xác những gì tôi có thể sử dụng làm sự ủng hộ cho tuyên bố của mình. Ai giúp tôi với? Cảm ơn!
Trong trường hợp này, điều này thậm chí không quan trọng khi chuỗi thực sự bắt đầu vì 'bảo đảm' gửi' xảy ra trước đó. Vì vậy, ngay cả khi việc triển khai thực thi của bạn sử dụng một số loại nhóm thread điên đã được khởi động trước khi khởi động JVM, bạn vẫn an toàn miễn là việc thực thi thực thi tuân theo đặc tả API. –
Đúng, nhưng tôi đang chọn để bảo vệ đối số như được trình bày trong câu hỏi - đó là, từ nguyên tắc đầu tiên, bỏ qua thực tế là người thi hành đưa ra nhiều bảo đảm hơn. Câu trả lời của bạn giải thích quan điểm của lớp thực thi đủ tốt. – Joni
@Joni Tôi không chắc chắn. Nếu luồng chạy phương thức 'execute()' thực hiện một cái gì đó giống như 'new Thread (new Y()).bắt đầu() ', sau đó tôi không nghĩ rằng' giá trị' có thể nhìn thấy trong bắt đầu 'Runnable' mà không có' giá trị' là 'dễ bay hơi'. Vì vậy, các bảo đảm xảy ra trước đó của các Executors được chỉ ra bởi @SergeyTachenov là cần thiết trong trường hợp này. Không? –