Đoạn mã sau có gây ra vấn đề tương tự hay không, nếu biến 'commonSet' của phương thức này thay vào đó là trường cấp lớp. Nếu nó là một trường cấp lớp, tôi sẽ phải bọc thêm để thiết lập hoạt động trong một khối được đồng bộ hóa vì HashSet không phải là luồng an toàn. Tôi có nên làm tương tự trong mã sau đây, vì nhiều luồng được thêm vào tập hợp hoặc thậm chí chuỗi hiện tại có thể tiếp tục thay đổi tập hợp.Chủ đề Biến an toàn cục bộ cuối cùng được chuyển cho chủ đề?
public void threadCreatorFunction(final String[] args) {
final Set<String> commonSet = new HashSet<String>();
final Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
commonSet.add(newValue());
}
}
};
new Thread(runnable, "T_A").start();
new Thread(runnable, "T_B").start();
}
Tham chiếu đến 'commonSet' bị 'khóa' bằng cách sử dụng final. Nhưng nhiều luồng hoạt động trên nó vẫn có thể làm hỏng các giá trị trong tập hợp (nó có thể chứa các bản sao?). Thứ hai, sự nhầm lẫn là do 'commonSet' là một biến mức phương thức - cùng một tham chiếu sẽ nằm trên bộ nhớ ngăn xếp của phương thức gọi (threadCreatorFunction) và bộ nhớ ngăn xếp của các phương thức chạy - điều này có đúng không?
Có khá một vài câu hỏi liên quan đến điều này:
- Why do variables passed to runnable need to be final?
- Why are only final variables accessible in anonymous class?
Nhưng, tôi không thể nhìn thấy họ nhấn mạnh vào chủ đề phần an toàn như chia sẻ/chuyền của mutables.
Xem thêm http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-differen – nos