Synchronized含义

Synchronized 锁定的是对象而非函数或代码。

每个Object都有一把锁(Lock),当进行到Synchronized语句或函数的时候,这把锁就会被当前的线程(thread)拿走,其他的(thread)再去访问的时候拿不到锁就被暂停了。

只有当Synchronized的是同一个对象的才是线程安全的(thread-safe)

class Test{

      public Synchronized void method1(){               //锁住的对象是this 即当前对象

          //........              

      }

        public void method2(){                                  // 锁住的对象是this  所以和method1是等同的,

                                                                                 //他们之间也是线程安全的。         

           Synchronized(this){                                     

                   //................

            }

     }

     public Synchronized static void method3(){      //锁住的对象是Test.class,注:

                                                                                       //Test.class 在虚拟机中只可能有一个,但是Test长生的对象 

                                                                                     //可以有多个,因为method3和method1,method2锁住的

                                                                                    //不同,所以他们之间不同步,不是线程安全的。

    }

    public void method4(){                                     //跟method3是相同的效果。

         Synchronized(Test.class){

              //............

          }

    }

}

这是Synchronized static 函数与Synchronized instance函数之间的区别。

-----------------------------------------

class Test implements Runnable{

    private int[] intArray = new int[10]

    public synchronized void addToArray(int[] ar){

  // modify the intArray 

  }

  public synchronized void subArray(int[] ary){

    // modify the intArray

}

  public int[] getIntArray(){
 

  return intArray;

  }

}

很多人看到上面这个例子马上可以断定这个Test一定是同步的。其实不然,因为他暴露了intArray给外界,所以可以不通过上面两个方法去修改intArray这个filed,假如intArray是public protected数据那就更不行了。那我要访问这个intArray怎么办,那就只好clone一个intArray了。

  public int[] getIntArray(){
 

  return intArray.clone();

  }

-------------------------------------------

private byte[] lock  =  new byte[0];//建议用使用这样的lock,因为这个不任何对象都经济。

创建一个元素个数为0的array,并不象创建对象那样需要调用构造函数,所以速度会快些,此外,内含元素的byte arrays往往在jvm中有着比int arrays 更紧凑的表述形式。

---------------------------------------------

long clocktime = 123123.1;

很多人看到上面这个操作的时候肯定会以为这个一定是安全的,因为会认为这是个原子操作。呵呵 错了!

long 数据一般采用64bit(跨越两个32bit word)表述。或许某些jvm实现产品将64-bit操作视为不可分割的(atomic),但现今大部分jvm实现产品都不这样。而是将它视为两个独立的32-bit操作。所以有可能发生旧值的前32bit以及其新值的后32bit组成。这个返回值是错误的。这是因为,面对64bit数据,jvm必须执行一次以上的读写动作。先前讨论的“私有专用副本”与“主内存”也是这个问题。想要改正这个问题,有两个选择:同步控制对clocktime变量的访问,或是将它声明为volatile。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值