鍍金池/ 問答/Java  網(wǎng)絡(luò)安全/ 下面這兩個同步塊是否互斥?

下面這兩個同步塊是否互斥?

Object obj=new Object();
Object obj2=obj;
synchronized(obj){}
synchronized(obj2){}

又如果這樣呢?

Object obj=new Object();
synchronized(obj){}
obj=new Object();
synchronized(obj){}
回答
編輯回答
孤影

上面兩個 synchronized 塊是互斥的.
所以基于這種鎖對象可能被誤用的情況, 建議用單獨的 final 對象做鎖, 而不要用與業(yè)務(wù)相關(guān)的變量:

final Object lock = new Object();
2018年6月17日 02:53
編輯回答
空痕

針對問題:如果多個線程在并發(fā)執(zhí)行執(zhí)行擁有相同鎖的同步塊synchronized(obj){}時,鎖對象obj被另一個線程給修改了指向,這個同步是否會失效?我有測試過這種情況沒有失效,可能是因為即便obj引用指向變了,當前還沒有執(zhí)行完的同步塊之間還是互斥的,因為對象還沒有被回收還在使用中。如果只有一個同步塊沒有執(zhí)行完,修改obj指向后,又執(zhí)行了一個synchronized(obj){},這個時候它們是不是互斥的呢?

測試代碼:

    static Object obj=new String("a");
    public static void main(String[] args) throws InterruptedException {
        class a extends Thread{
            @Override
            public void run() {
                synchronized(obj){
                    for (int i = 0; i < 10000; i++) {
                        if(i%10==0)System.out.println(obj+",0");
                    }
                }
            }
        }
        new a().start();
        Thread.sleep(10);
        obj=new String("b");
        class b extends Thread{
            @Override
            public void run() {
                synchronized(obj){
                    for (int i = 0; i < 10000; i++) {
                        if(i%10==0)System.out.println(obj+",1");
                    }
                }
            }
        }
        new b().start();
    }

測試結(jié)果:兩個線程輸出有交叉,同步確實會失效

2018年3月14日 04:33
編輯回答
撥弦

鎖這個標記是在 對象的Header的markword中存在的,是和一個對象綁定的,而不是和對象的引用綁定,所以第一個問題是互斥的,你的第二個問題有問題,因為你寫synchronized(obj){}的時候,一般是以內(nèi)部類的形式寫在runnable或者Thread中,但是內(nèi)部類引用的外部變量就必須是final的,而你這個obj都變了,就不是final,所以這段代碼你是咋寫出來的?

2017年12月26日 08:38