java 線程Thread同步synchronized使用

很多人都知道,在Java多線程編程中,有一個重要的關鍵字,synchronized。但是很多人看到這個東西會感到困惑:“都說同步機制是通過對象鎖來實現的,但是這麼一個關鍵字,到底有什麼作用呢?”

synchronized定義在方法中,保證在多線程運行此方法的時候,可以保證方法的逐步執行,即:當有線程佔用此資源的時候,其他線程進行等待,當前一線程執行完,後一線程繼續執行,從而保證數據的正確性。

package com.ada;

/**
 * @author fanyanyan
 * @Title: VolatileDemo
 * @ProjectName JavaProject
 * @date 2019/5/21 9:02
 */

public class VolatileDemo {

    /**
     * volatile只有可見性,無法保證原子性
     */

    private volatile int num = 0;

    public int getNum() {

        return this.num;

    }

    public synchronized void increase() {

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (this.num % 2 == 0) {
            this.num++;
        } else {
            this.num--;
        }
//        this.num++;

        System.out.println("過程中 " + num);

    }

    public static void main(String[] args) {
        final VolatileDemo volatileDemo = new VolatileDemo();

        for (int i = 0; i < 500; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    volatileDemo.increase();
                }
            }).start();
            System.out.println("=======" + i);

        }

        //如果還有子線程在執行,主線程讓出cpu資源,直到子線程執行完畢,主線程繼續執行
//        System.out.println(Thread.activeCount()); 
        while (Thread.activeCount() > 2) { // 大於2是因爲存在主線程和其守護線程
            Thread.yield();
        }
        System.out.println("-------num:" + volatileDemo.getNum());

    }
}

當方法中不使用synchronized時,當數據循環次數變多的情況下,數據的準確性就會降低。

package com.ada;

/**
 * @author fanyanyan
 * @Title: VolatileDemo
 * @ProjectName JavaProject
 * @date 2019/5/21 9:02
 */

public class VolatileDemo {

    /**
     * volatile只有可見性,無法保證原子性
     */

    private volatile int num = 0;

    public int getNum() {

        return this.num;

    }
// 不使用synchronized,但循環次數爲500次時,很可能會出錯
    public void increase() {

        try {
            //休眠更容易重現結果不爲0的情況
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (this.num % 2 == 0) {
            this.num++;
        } else {
            this.num--;
        }
//        this.num++;

        System.out.println("過程中 " + num);

    }

    public static void main(String[] args) {
        final VolatileDemo volatileDemo = new VolatileDemo();

        for (int i = 0; i < 500; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    volatileDemo.increase();
                }
            }).start();
            System.out.println("=======" + i);

        }

        //如果還有子線程在執行,主線程讓出cpu資源,直到子線程執行完畢,主線程繼續執行
//        System.out.println(Thread.activeCount());
        while (Thread.activeCount() > 2) {
            Thread.yield();
        }
        System.out.println("-------num:" + volatileDemo.getNum());

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章