Synchnorized 辨析 (1)

示例代码:


public class SyncTest {

 

      private ListString list= new ArrayListString();

 

      public void syncAddPrint(){

             synchronized(list){

                    for(int i = 0; i 10; i++) {

                                                                     list.add(""+ i);

                          System.out.println(list);

                    }

             }

     } 

      public void syncAdd2(){

             synchronized(list){

                    list.add("A");

                    list.add("B");

                    list.add("C");

             }

      }

 

      public void  noSyncAdd() {

             list.add("X");

             list.add("Y");

             list.add("Z");

      }

 

      public void noSyncNew(){

             list= new ArrayListString();

             list.add("Ha");

             list.add("Ha");

             list.add("Ha");

      }

 

      

      public static void main(String[] args){

             final SyncTest test =new SyncTest();

 

             Thread thread1 = new Thread() {

                    public void run() {

                          test.syncAddPrint();

                    }

             };

             thread1.start();

 

             Thread thread2 = new Thread() {

                    public voidrun() {

                          test.syncAdd2();

                    }

             };

             thread2.start();

 

             Thread thread3 = new Thread() {

                    public voidrun() {

                          test.noSyncAdd();

                    }

             };

             thread3.start();

 

             Thread thread4 = new Thread() {

                    public voidrun() {

                          test.noSyncNew();

                    }

             };

             thread4.start();

      }

 

}

 

输出结果可能是:

[0]

[0,1]

[0, 1,2]

[0, 1, 2,X, 3]

[0, 1, 2,X, 3, Y, 4]

[Ha, 5]

[Ha, 5,Z, 6]

[Ha, 5,Z, 6, Ha, Ha, 7]

[Ha, 5,Z, 6, Ha, Ha, 7, 8]

[Ha, 5,Z, 6, Ha, Ha, 7, 8, 9]


thread1执行方法syncAddPrint的过程中,thread1获得了锁list


thread1获得锁list未释放线程thread2执行syncAdd2,但是得不到锁list故而被阻塞。


thread3执行noSyncAdd,不需要获得锁list所以在方法中轻易将锁list的元素改变


thread4执行noSyncNew,不需要获得锁list所以在方法中轻易将锁list替换成另一个对象。


thread3thread4这些对list的改变动作都是在thread1还持有锁list的情况下发生的。

 

由此可见,要保证锁list在被某线程持有的情况下不被改变,则必须访问锁list的所有代码块都必须使用synchronized(list)才可以,一旦某个方法遗漏,则不可保证。