2012-11-04 41 views
6

Trong Concurrency in Practice, nó nói rằng bạn có thể sử dụng các biến không ổn định nếuConcurrency in Practice - dễ bay hơi ++

Viết vào biến không phụ thuộc vào giá trị hiện tại của nó.

Vì vậy, nếu bạn có một chia sẻ, có thể thay đổi biến a, và tất cả các chủ đề bao giờ làm gì để nó là đi a++ (họ không có được giá trị, họ chỉ ++).

Sau đó, theo báo giá, bạn sẽ có thể làm cho nó volatile mặc dù a++ không phải là nguyên tử, đúng không?

+2

Không phải là ++; tương đương với a = a + 1; ? Và nếu nó là như vậy, bạn phải đọc một, sau đó viết một + 1 đến a. – Burkhard

Trả lời

7

Không, sử dụng ++ trên một biến volatilekhông ThreadSafe, vì

a++ 

tương đương với:

int temp = a; 
temp = temp + 1; 
a = temp; 

Vì vậy, ghi lại a có thể xảy ra sau thread khác đã sửa đổi a kể từ khi chuỗi của bạn đọc nó, vì vậy a++, ngay cả khi a dễ bay hơi, là không phải là luồng an toàn.

Bạn có thể sử dụng AtomicInteger, thực hiện tăng luồng nguyên tử theo chủ đề.

+1

+1 Kỹ thuật, nhưng nó chỉ tương đương với nếu 'a' là' int'. – arshajii

6

một ++ đọc giá trị của một, vì nó tương đương với

  • đọc một
  • tăng giá trị đọc
  • gán giá trị mới cho một

Vì vậy, không, bạn có thể không an toàn sử dụng biến biến động trong trường hợp này.

1

một ++ không nguyên tử, nó tương đương với

  • lấy một
  • thêm 1
  • lưu trữ kết quả trở thành một

Vì vậy, bạn vẫn có thể "cập nhật bỏ lỡ" , nếu một sợi khác bị cản đường - dễ bay hơi không được thiết kế để ngăn chặn điều đó, đó là những gì "khối đồng bộ" và "khóa" được cho.

Thực tế một biến động chỉ ảnh hưởng đến khả năng hiển thị giữa các luồng, vì không được lưu trong bộ đệm cục bộ, do đó các luồng khác nhau (chạy trên lõi hoặc bộ xử lý khác nhau) có thể "xem" giá trị mới của nó ngay lập tức.

3

- dễ bay hơi làm những điều sau đây:

  • Một lĩnh vực được đánh dấu volatile, sẽ có giá trị của nó ghi vào bộ nhớ ngaytrong nghỉ hưu, giá trị nó được đọc từ bộ nhớ.

  • Ngăn chặn bộ nhớ đệm của giá trị trong chủ đề.

Ví dụ:

a++có thể được giải thích như sau:

- Reading về giá trị của vị trí bộ nhớ được đặt tên một.

- Tăng giá trị.

- Viết giá trị gia tăng mới cho vị trí bộ nhớ có tên là a.

Bây giờ toàn bộ quá trình trên là notThread-Safe,++ (Tăng toán) trong Java là không phải là một Tuyên bố nguyên tử.

- Better sử dụng synchronized từ khóa hoặc nếu bạn không thích sử dụng nó, đi với AtomicInteger Class.

Các vấn đề liên quan