Để sử dụng đối tượng không thay đổi hiệu quả mà không cần final
trường theo cách an toàn, bạn cần sử dụng một trong các thành phần xuất bản an toàn khi tạo đối tượng cho các chủ đề khác sau khi khởi tạo. nhà nước (từ Java Concurrency in Practice):
- Khởi tạo một tham chiếu đối tượng từ một initializer tĩnh;
- Lưu trữ tham chiếu đến nó vào trường dễ bay hơi hoặc AtomicReference;
- Lưu trữ tham chiếu đến trường đó vào trường cuối cùng của đối tượng được tạo đúng; hoặc
- Lưu trữ tham chiếu đến trường đó vào trường được khóa cẩn thận.
lĩnh vực Tuyên bố của đối tượng bất biến của bạn như final
phiên bản hạn chế này (ví dụ: nó đảm bảo rằng nếu đề khác nhìn thấy một tham chiếu đến đối tượng, họ cũng thấy final
lĩnh vực của mình trong trạng thái khởi tạo đầy đủ). Tuy nhiên, trong trường hợp chung nó không đảm bảo rằng các chủ đề khác có thể thấy một tham chiếu đến đối tượng ngay sau khi nó được xuất bản, vì vậy bạn vẫn có thể cần phải sử dụng ấn phẩm an toàn để đảm bảo nó.
Lưu ý rằng nếu đối tượng của bạn thực hiện một giao diện, bạn có thể sử dụng một cách tiếp cận được sử dụng bởi Collections.unmodifiableList()
, vv:
class ImmutableFooWrapper implements IFoo {
private final IFoo delegate; // final provides safe publication automatically
public ImmutableFooWrapper(IFoo delegate) {
this.delegate = delegate;
}
...
}
public IFoo immutableFoo(IFoo foo) {
return new ImmutableFooWrapper(foo);
}
Bạn có ý nghĩa gì khi * loại bỏ các phương thức sửa đổi * phương pháp sửa đổi? Ném một ngoại lệ từ tất cả những người định cư? Điều này sẽ vi phạm [nguyên tắc thay thế Liskov] (http://en.wikipedia.org/wiki/Liskov_substitution_principle). Nhưng có, lớp này ** sẽ ** được an toàn thread. –
Có, ném ngoại lệ thời gian chạy hoặc ghi đè chúng bằng một cơ thể trống có thể với một số lần ghi nhật ký. Tôi biết nó vi phạm LSP. – pcjuzer