Synchronized(对象锁)和Static Synchronized(类锁)的区别

本文详细探讨了Java中的synchronized关键字在对象锁和类锁(全局锁)上的应用。对象锁是针对类的实例,限制其他线程同时访问该实例的synchronized方法或代码块,而类锁(全局锁)通过static synchronized修饰的方法或代码块,限制所有实例对这部分代码的并发访问。两者的主要区别在于锁的对象不同,对象锁锁定的是实例,类锁锁定的是类。同步代码块和同步方法在效率上也存在差异,同步代码块通常比同步方法更高效。文章通过示例代码和分析展示了这两种锁的使用和效果。
摘要由CSDN通过智能技术生成

Synchronized和Static Synchronized区别

通过分析这两个用法的分析,我们可以理解java中锁的概念。一个是实例锁(锁在某一个实例对象上,如果该类是单例,那么该锁也具有全局锁的概念),一个是全局锁(该锁针对的是类,无论实例多少个对象,那么线程都共享该锁)。实例锁对应的就是synchronized关键字,而类锁(全局锁)对应的就是static synchronized(或者是锁在该类的class或者classloader对象上)。下面的文章做了很好的总结:

 

 

1.synchronized与static synchronized 的区别

       synchronized是对类的当前实例(当前对象)进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块,注意这里是“类的当前实例”, 类的两个不同实例就没有这种约束了。

那么static synchronized恰好就是要控制类的所有实例的并发访问,static synchronized是限制多线程中该类的所有实例同时访问jvm中该类所对应的代码块。实际上,在类中如果某方法或某代码块中有 synchronized,那么在生成一个该类实例后,该实例也就有一个监视块,防止线程并发访问该实例的synchronized保护块,而static synchronized则是所有该类的所有实例公用得一个监视块,这就是他们两个的区别。也就是说synchronized相当于 this.synchronized,而static synchronized相当于Something.synchronized.(后面又讲解)

 

 

         一个日本作者-结成浩的《java多线程设计模式》有这样的一个列子:

[java] view plaincopy

  1. pulbic class Something(){  

  2.     public synchronized void isSyncA(){}  

  3.     public synchronized void isSyncB(){}  

  4.     public static synchronized void cSyncA(){}  

  5.     public static synchronized void cSyncB(){}  

  6. }  

 

 

       那么,假如有Something类的两个实例x与y,那么下列各组方法被多线程同时访问的情况是怎样的?

[java] view plaincopy

  1. a. x.isSyncA()与x.isSyncB()   

  2. b. x.isSyncA()与y.isSyncA()  

  3. c. x.cSyncA()与y.cSyncB()  

  4. d. x.isSyncA()与Something.cSyncA()  

 

 

      这里,很清楚的可以判断:

a,都是对同一个实例(x)的synchronized域访问,因此不能被同时访问。(多线程中访问x的不同synchronized域不能同时访问)

 

如果在多个线程中访问x.isSyncA(),因为仍然是对同一个实例,且对同一个方法加锁,所以多个线程中也不能同时访问。(多线程中访问x的同一个synchronized域不能同时访问)

b,是针对不同实例的,因此可以同时被访问(对象锁对于不同的对象实例没有锁的约束)

c,因为是static synchronized,所以不同实例之间仍然会被限制,相当于Something.isSyncA()与 Something.isSyncB()了,因此不能被同时访问。

那么,第d呢?,书上的 答案是可以被同时访问的,答案理由是synchronzied的是实例方法与synchronzied的类方法由于锁定(lock)不同的原因。

个人分析也就是synchronized 与static synchronized 相当于两帮派,各自管各自,相互之间就无约束了,可以被同时访问。

举个例子:

Java代码  

  1. public class TestSynchronized   

  2. {    

  3.     public synchronized void test1()   

  4.     {    

  5.               int i = 5;    

  6.               while( i-- > 0)   

  7.               {    

  8.                    System.out.println(Thread.currentThread().getName() + " : " + i);    

  9.                    try   

  10.                    {    

  11.                         Thread.sleep(500);    

  12.                    }   

  13.                    catch (InterruptedException ie)   

  14.                    {    

  15.                    }    

  16.               }    

  17.     }    

  18.       

  19.     public static synchronized void test2()   

  20.     {    

  21.          int i = 5;    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值