synchronized的作用是什么?

解决方案 »

  1.   

    //只允许一个线程执行同一个实例的myMethod方法
    synchronized public void myMethod( ) { ... }
    public void myMethod( ) { synchronized (myObject) {
    //只允许一个线程通过myMethod对myObject的操作
    ...//对myObject的操作
    } }
      

  2.   

    java对于同步做了很多工作,屏蔽了很多复杂的锁功能,简单的使用synchronize就可以实现资源同步共享.相对于其他语言来说,java的同步的确为程序员屏蔽了很多繁琐的细节.但也许正因为它使用起来很方便,很多人反而忽视了它的真正原理.
      应该怎样理解synchronize呢?简单的说就是让一段代码在一个对象上同步.
    实例1:
    Object lock=new Object();
    public void test1(){
       synchronized(lock){
          //doSomthing1
       }
    }
    public void test2(){
       synchronized(lock){
          //doSomthing2
       }
    }
    无疑,两个方法分别在lock上同步,也就是说doSomething1和doSomething2是在lock上同步的,不可以同时调用
     
    实例2:
    public synchronized void test1(){
          //doSomthing1
    }
    public synchronized void test2(){
          //doSomthing2
    }
    test1和test2之间是同步的吗?
    如果调用一下就会发现,不只test1只能同时有一个使用者,test1和test2之间也不可以同时被调用
     
    实例3:
    public synchronized void test1(){
          //doSomthing1
    }
    public void test2(){
      synchronized (this){
          //doSomthing2
      }
    }
    doSomething1 和 doSomething2可以同时被调用吗?也不可以,他们也是同步的。
     
    由此可以看出,
    public synchronized void test1(){
          //doSomthing1
    }
    等同于
    public void test1(){
      synchronized (this){
          //doSomthing1
      }
    }
    都是在this这个实例上同步的。
     
      这就引出了一个隐藏的炸弹,在使用synchronized 的时候,一定要注意同步锁到底是什么,如果某个方法使用了synchronized 来修饰,那么这个方法会和所有在这个实例上同步的代码块同步。
      一个类class MyTest 中有一个方法synchronized test();
      实例MyTest  myTest=new MyTest();
      如果在其他地方有调用
      public void fuc(){
         synchronized(myTest){
             //doSomething
         }
      }
      那么一定要考虑doSomething与myTest.test()之间的同步问题。
     
     
     知道了synchronized 的用法,还有一个细节要考虑。
     Object lock=new Object();
     public void test1(){
       synchronized (lock){
         //doSomething
       }
     }
     public void test2(){
       synchronized (lock){
          test1();
       }
     }
     调用test2时会出现什么问题?
     java把synchronized设计的如此完美,对于重复出现的同一实例上的同步区域,以最大范围为准.所以这样的调用实际上相当于只对test2同步。