synchronized 不是萬能,錯誤加鎖

Java支持多個線程同時訪問一個對象或者對象的成員變量,synchronized 關鍵字可以修飾方法或者同步代碼塊的方法,確保多個線程在同一時刻,只能有一個線程處於方法或者同步代碼塊中,保證了線程對變量訪問的可見性和排他性

 

public class Demo052501 {

    private static class ThreadDemo implements Runnable{
        private Integer i;

        public  ThreadDemo(Integer i){
            this.i = i;
        }
        @Override
        public void run() {
            synchronized (i){
                Thread thread = Thread.currentThread();
                System.out.println(thread.getName() + "-------"+ i+ "@----" + System.identityHashCode(this.i));
                i++;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        ThreadDemo worker = new ThreadDemo(1);

        for(int i =0;i<6;i++){
            new Thread(worker).start();
        }
    }
}

預期輸出:

i : 1-2-3-4-5-6

實際輸出:

 

錯誤加鎖原因:

.class 文件反編譯,i++ 的代碼爲:

Integer.valueOf()

synchronized 內置鎖,鎖的是對象,保證對象唯一!!!

 

解決方法

public class Demo052501 {

    private static class ThreadDemo implements Runnable{
        private Integer i;
        private Object o = new Object();

        public  ThreadDemo(Integer i){
            this.i = i;
        }
        @Override
        public void run() {
            synchronized (o){
                Thread thread = Thread.currentThread();
                System.out.println(thread.getName() + "-------"+ i+ "@----" + System.identityHashCode(this.i));
                i++;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        ThreadDemo worker = new ThreadDemo(1);

        for(int i =0;i<6;i++){
            new Thread(worker).start();
        }
    }
}

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