雙重校驗鎖為什么要判斷兩次


  今天寫synchronized用例的時候,兩個線程共享一個對象數據,當操作i的時候,在同步代碼塊外面判斷了一次i<100,但是每一次跑,都會出現i=100,的情況,此時我想起了單例模式的雙重校驗鎖,為什么要判斷兩次呢?因為可能出現線程1和線程2,在i=99的時候,同時判斷了一次,都進到了for循環里面,此時線程1進入同步代碼塊,線程2進如阻塞隊列,當線程1跑出代碼塊后,線程2進入同步代碼塊,線程1對i進行加一操作后,i變成了100,線程2輸出100,所以要在同步代碼塊中再加一次判斷,判斷i的值

  synchronized代碼塊使用起來比synchronized方法要靈活得多。因為也許一個方法中只有一部分代碼只需要同步,如果此時對整個方法用synchronized進行同步,會影響程序執行效率。而使用synchronized代碼塊就可以避免這個問題,synchronized代碼塊可以實現只對需要同步的地方進行同步

import java.util.ArrayList;

public class SynchronizedTest2 {
    public static void main(String[] args) throws InterruptedException {
        SychronizedTest2 synchronized2 = new SychronizedTest2();
        Data data = synchronized2.new Data();
        new Thread(new Runnable() {
            @Override
            public void run() {
                data.insert();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                data.insert();
            }
        }).start();
        Thread.currentThread().sleep(3000);
    }
    class Data{
        private ArrayList<Integer> arr = new ArrayList<>();
        private int i = 0;
        public void insert(){
            for(;i<100;i ++)
                synchronized(this){
                    if(i<100){
                        if(!arr.contains(i)){
                            System.out.println(Thread.currentThread().getName()+" 正在插入"+i);
                            arr.add(i);
                        }
                    }
                }
            }
        }
    }

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM