java併發編程學習之synchronize(一)

線程安全問題

java併發編程學習之基礎概念提到,多線程的劣勢之一,有個線程安全問題,如今看看下面的例子。java

public class NotSafeDemo {
    private int num = 0;

     public void add(int value) {
        try {
            num = num + value;
            Thread.sleep(100);
            System.out.println("num:" + num);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        NotSafeDemo synchronizeDemo = new NotSafeDemo();
        AddThread1 addThread1 = new AddThread1(synchronizeDemo);
        AddThread2 addThread2 = new AddThread2(synchronizeDemo);
        addThread1.start();
        addThread2.start();
    }
}

class AddThread1 extends Thread {
    NotSafeDemo synchronizeDemo;

    public AddThread1(NotSafeDemo synchronizeDemo) {
        this.synchronizeDemo = synchronizeDemo;
    }

    @Override
    public void run() {
        synchronizeDemo.add(1);

    }
}

class AddThread2 extends Thread {
    NotSafeDemo synchronizeDemo;

    public AddThread2(NotSafeDemo synchronizeDemo) {
        this.synchronizeDemo = synchronizeDemo;
    }

    @Override
    public void run() {
        synchronizeDemo.add(2);
    }
}

運行結果以下:算法

clipboard.png

爲何會不安全呢,在java併發編程學習之基礎概念提過,兩個線程共享一個進程的資源,也就是說,num這個值,是共享的,在還沒輸出num的時候,已經被第二個線程,改爲3,因此兩次輸出都是3。那麼,該怎麼解決呢,很簡單,在方法前加個同步鎖synchronized。編程

synchronized public void add(int value) {
        try {
            int temp = num;
            num = num + value;
            Thread.sleep(100);
            System.out.println(value + "+" + temp + "=" + num);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

運行結果以下:segmentfault

clipboard.png

clipboard.png

有兩種狀況,是由於看誰先搶佔鎖,可是輸出的算法結果是正確的。安全

相關文章
相關標籤/搜索