深入了解synchronized及对象锁
1 , Synchronized锁定的是对象而非函数或代码。2 , 每个Object只有一把锁(Lock)与之关联,当进行到Synchronized语句或函数的时候,这把锁就会被当前的线程(thread)拿走,其他的(thread)再去访问的时候拿不到锁就被暂停了3, 只有当Synchronized的是同一个对象的才是线程安全的(thread-safe)如: 1) public Synchronized void method1 : 锁住的是该对象,类的其中一个实例 , 当该对象(仅仅是这一个对象)在不同线程中执行这个同步方法时,线程之间会形成互斥.达到同步效果,但如果不同线程同时对该类的不同对象执行这个同步方法时,则线程之间不会形成互斥,因为他们拥有的是不同的锁. 2) Synchronized(this){ //TODO } 同一 3) public Synchronizedstatic void method3 : 锁住的是该类,当所有该类的对象(多个对象)在不同线程中调用这个static 同步方法时,线程之间会形成互斥,达到同步效果 , 但如果多个线程同时调用method1 , method3,则不会引互斥,具体讲看最后讲解. 4) Synchronized(Test.class){ //TODo} 同三 5) synchronized(o) {} 这里面的o可以是一个任何Object对象或数组,并不一定是它本身对象或者类,谁拥有o这个锁,谁就能够操作该块程序代码.这里面1) 与2) 是线程安全的,但1)与3) , 2)与3) 他们所拥有的锁不一样,故不是同步的,不是线程安全的.
最后, synchronized 所同步的代码应该尽量少.如果没有必要同步的就不要列为其中 联想到数据库的并发控制假如有如下操作 1) 从数据库中读取数据 2) 修改数据 3) 提交数据解决方案一1) 读取数据synchronized(XXX){ 2)修改数据 3) 提交数据}解决方案二synchronized(XXX){ 1) 读取数据 2)修改数据 3) 提交数据}解决方案三synchronized(XXX){ 3) 提交数据}这里面到底用哪一种方案视具体情况而定, 要注意的是synchronized(同步)的代价,开销是很大的. |