2013-03-08 35 views
8

Tôi biết hoạt động gia tăng không phải là nguyên tử trong C++ mà không cần khóa.iinc nguyên tử trong Java?

JVM có thêm bất kỳ khóa nào khi triển khai lệnh iinc không?

Trả lời

17

Không nó không

  • Lấy giá trị hiện tại của c.
  • Tăng giá trị đã truy xuất lên 1.
  • Lưu trữ giá trị gia tăng trở lại trong c.

Java Documentation for Atomicity and Thread Interference

Bạn cần phải sử dụng một trong hai synchronized từ khóa hoặc sử dụng AtomicXXX phương pháp cho sự an toàn Chủ đề.

CẬP NHẬT:

public synchronized void increment() { 
    c++; 
} 

hoặc

AtomicInteger integer = new AtomicInteger(1); 
//somewhere else in code 
integer.incrementAndGet(); 

Cũng đọc: Is iinc atomic in Java?

+0

bạn nên đọc tài liệu đồng thời của Java, điều này khá tốt cho việc hiểu các khái niệm cơ bản về Java Concurrency. –

+0

Cảm ơn, đọc nó ngay bây giờ. Chấp nhận sau 1 phút. – StarPinkER

+0

Chắc chắn rất vui được trợ giúp! –

3

Không nó không phải là nguyên tử, các bytecode có thể nhận được xen kẽ với các chủ đề khác.

6

Không phải không và nó có thể gây ra vấn đề thực sự. Xét nghiệm này được cho là để in 200000000 nhưng nó không do sợi can thiệp

static int n; 

public static void main(String[] args) throws InterruptedException { 
    Runnable r = new Runnable() { 
     public void run() { 
      for(int i = 0; i < 100000000; i++) { 
       n++; 
      } 
     } 
    }; 
    Thread t1 = new Thread(r); 
    Thread t2 = new Thread(r); 
    t1.start(); 
    t2.start(); 
    t1.join(); 
    t2.join(); 
    System.out.println(n); 
} 

Lưu ý rằng volatile không giải quyết được vấn đề.

+0

+1 cũng bao gồm các biến động:) –

+1

Thực ra, mã này thậm chí không sử dụng lệnh 'IINC' để tăng trường' n'. 'IINC' chỉ được sử dụng cho các biến cục bộ, và trong trường hợp này chỉ cho' i ++ '. – Clashsoft

1

i ++ không phải là nguyên tử trong java.
Nó là tốt hơn để sử dụng

AtomicInteger atomic= new AtomicInteger(1); 

Có nhiều phương pháp được định nghĩa như

atomic.getAndDecrement(); 
atomic.getAndIncrement(); 
atomic.decrementAndGet(); 
atomic.incrementAndGet(); 

bất kỳ hoạt động với phương pháp trên sẽ là nguyên tử.

Lớp học này đi kèm theo gói java.util.concurrent.atomic. Java 1.5 đã thêm nhiều tính năng cho sự an toàn và đồng thời của chuỗi.

0

Nó không phải là nguyên tử. Đây là mã byte được tạo ra cho một bài thặng dư của một int tĩnh:

0 getstatic 18; // Load value of variable. 
3 iconst_1; 
4 iadd; 
5 putstatic 18; // Store value. 
6

{Mặc dù đã có một câu trả lời được chấp nhận, tôi muốn xóa cái gì đó lên, do đó câu trả lời muộn và về mặt kỹ thuật không cần thiết}

Câu trả lời cho câu hỏi của bạn tùy thuộc vào việc bạn có ý là hướng dẫn IINC hay không, câu trả lời khác là gì, nhà điều hành ++.

Sử dụng ++ trên trường tĩnh hoặc trường hợp không gì hơn là nhận, tăng và đặt, vì vậy nó là không nguyên tử (các câu trả lời khác giải thích chi tiết hơn).

Nhưng

Vì bạn hỏi nếu IINChướng dẫn là nguyên tử, đây không phải là câu trả lời thực sự. Trong thực tế, không có câu trả lời cho câu hỏi này giải quyết hướng dẫn , tất cả chúng dường như được dựa trên toán tử đang được sử dụng trên các trường mẫu hoặc trường tĩnh.


Các hướng dẫn IINCchỉ hoạt động trên các biến địa phương. Như tên cho thấy, chúng chỉ là địa phương và chỉ có thể truy cập từ phạm vi rất hạn chế. Do đó, không thể truy cập một biến cục bộ từ một Thread khác. Điều này có nghĩa là nó không quan trọng hay không chỉ lệnh là nguyên tử.

+0

Cảm ơn câu trả lời của bạn! – withparadox2

+0

Được làm rõ một cách rõ ràng! Đã thêm liên kết vào câu trả lời của bạn từ câu trả lời của tôi. –

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