Tôi đồng ý với câu trả lời @ Kumar.
Dễ bay hơi là không đủ - nó có một số ý nghĩa đối với thứ tự bộ nhớ, nhưng không đảm bảo nguyên tử của ++.
Điều thực sự khó khăn về lập trình đa luồng là các sự cố có thể không hiển thị trong bất kỳ số lượng kiểm tra hợp lý nào. Tôi đã viết một chương trình để chứng minh vấn đề, nhưng nó có chủ đề mà không làm gì ngoài quầy tăng dần. Mặc dù vậy, số lượng nằm trong khoảng 1% câu trả lời đúng. Trong một chương trình thực sự, trong đó các luồng có công việc khác để làm, có thể có một xác suất rất thấp của hai luồng làm ++ đóng đủ để đồng thời hiển thị vấn đề. Không thể kiểm tra độ chính xác đa luồng, nó phải được thiết kế.
Chương trình này thực hiện cùng một nhiệm vụ đếm bằng cách sử dụng một int tĩnh đơn giản, int dễ bay hơi và AtomicInteger. Chỉ AtomicInteger liên tục nhận được câu trả lời đúng. Một sản lượng điển hình trên một đa với 4 lõi kép ren là:
count: 1981788 volatileCount: 1982139 atomicCount: 2000000 Expected count: 2000000
Dưới đây là mã nguồn:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class Test {
private static int COUNTS_PER_THREAD = 1000000;
private static int THREADS = 2;
private static int count = 0;
private static volatile int volatileCount = 0;
private static AtomicInteger atomicCount = new AtomicInteger();
public static void main(String[] args) throws InterruptedException {
List<Thread> threads = new ArrayList<Thread>(THREADS);
for (int i = 0; i < THREADS; i++) {
threads.add(new Thread(new Counter()));
}
for (Thread t : threads) {
t.start();
}
for (Thread t : threads) {
t.join();
}
System.out.println("count: " + count + " volatileCount: " + volatileCount + " atomicCount: "
+ atomicCount + " Expected count: "
+ (THREADS * COUNTS_PER_THREAD));
}
private static class Counter implements Runnable {
@Override
public void run() {
for (int i = 0; i < COUNTS_PER_THREAD; i++) {
count++;
volatileCount++;
atomicCount.incrementAndGet();
}
}
}
}
Nguồn
2012-11-28 07:01:49
Bạn phải bảo vệ truy cập đồng thời đến một 'int' mình. Tuy nhiên, 'AtomicInteger' được thiết kế để an toàn chỉ. – reprogrammer
'static' không có liên quan gì đến đa luồng. –
Theo hiểu biết của tôi, chúng tôi sử dụng biến biến động thay vì biến tĩnh trong môi trường đa luồng. – Vishal