Java使用原子類進行多線程的 i++ 操做示例

使用AtomicInteger原子類進行 i ++ 操做 能夠有相似 synchronized 實現同步的效果。java

原子操做是不能分割的總體,沒有其餘線程可以中斷或檢查正在原子操做中的變量。一個原子類型就是一個原子操做可用的類型,它能夠在沒有鎖的狀況下作到線程安全。安全

示例1:ide

AddCountThread.javathis

import java.util.concurrent.atomic.AtomicInteger;

public class AddCountThread extends Thread {
    private AtomicInteger count = new AtomicInteger(0);

    @Override
    public void run() {
        for(int i=0;i<10000;i++){
            System.out.println(count.incrementAndGet());
        }
    }
}

Run_Atomic.javaatom

public class Run_Atomic {
    public static void main(String[] args) {
        AddCountThread countService = new AddCountThread();
        Thread t1 = new Thread(countService);
        t1.start();
        Thread t2 = new Thread(countService);
        t2.start();
        Thread t3 = new Thread(countService);
        t3.start();
        Thread t4 = new Thread(countService);
        t4.start();
        Thread t5 = new Thread(countService);
        t5.start();
    }
}

輸出結果成功地累加到 50000 線程

可是原子類也並非徹底安全的,好比如下例子code

示例2:rem

MyService.javaget

import java.util.concurrent.atomic.AtomicLong;

public class MyService {
    public static AtomicLong aiRef = new AtomicLong();
    public void addNum() {
        System.out.println(Thread.currentThread().getName() + "加了100以後的結果是:" + aiRef.addAndGet(100));
        aiRef.addAndGet(1);
    }
}

MyThread.java同步

public class MyThread extends Thread {
    private MyService myService;
    public MyThread (MyService myService) {
        super();
        this.myService = myService;
    }

    @Override
    public void run() {
        myService.addNum();
    }
}

Run3_1.java

public class Run3_1 {
    public static void main(String[] args) {
        try {
            MyService myService = new MyService();
            MyThread[] array = new MyThread[8];
            for(int i=0;i<array.length;i++) {
                array[i] = new MyThread(myService);
            }
            for (int i = 0;i<array.length;i++ ){
                array[i].start();
            }
            Thread.sleep(1000);
            System.out.println(myService.aiRef.get());
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

輸出結果:

出現這種狀況是由於,addAndGet()方法是原子性的,但方法和方法之間的調用卻不是原子的。解決這樣的問題必須用到同步。

給addNum() 方法加上 同步鎖既解決以上問題。

相關文章
相關標籤/搜索