synchronized锁住的到底是谁???

谁会被锁住

一般来说,synchronized 从锁的是谁的纬度上一共有两种情况;

  1. 锁住类
  2. 锁住实例对象

类锁与实例对象锁的区别

实例锁

类声明后,new出来的实例对象,在堆中都有自己的独立空间和引用地址,这时候我们可以认为这些实例都是独立的个体,所以在实例上加的锁与其它的实例就没有关系,互不影响

类锁

类信息是存放在方法区的,整个JVM中只有一份,方法区是被所有线程共享的,所以类也是被所有线程共享的。
而静态成员(static修饰的成员、方法)是跟类一起加载的,也是存放在方法区,被所有线程共享。

参考链接:面试官:请说以下对象锁与类锁的区别

synchronized 的各种场景

synchronized 在静态方法上进行了声明则锁的是这个类,也就是我们常说的类锁,如下:

 public static synchronized  void test(){};

synchronized 普通方法上进行了声明,或者是synchronized(this),则锁的是这个类的实例对象,如下:

public  class Test{
 // synchronized 在普通方法`进行了声明
 public synchronized void test1(){};

 // 同步代码块 这里锁的也是这个类的实例对象
 public void test(){
 		synchronized(this){
 		   ...
 		}
 }
}

同步代码块synchronized(Demo.class)锁的是Demo这个:如下:

 public class Demo{
 }  

 public class Test{
    public void test(){
       synchronized(Demo.class)
   }
 }

synchronized(object)锁的是这个实例对象,如下:

 public class Demo{
 }  

 public class Test{
   private Demo demo = new Demo();
  
    public void test(){
       synchronized(demo)
   }
   
 }

参考链接

有一个点需要特别注意:
类锁与实例锁其实都是加锁,并不是将整个类锁住了,也不是这个类/实例中所有方法都被锁住了,而是控制了某个synchronized方法或者synchronized代码块访问
参考下方代码:

public class Test{
   
    public  void test1(){
        System.out.println("test1");
    }
    
    public void test2(){
        synchronized (this){
            System.out.println("test2");
        }
    }
}

test2中有加锁 synchronized (this),若想继续执行后续代码,需要先获取当前实例对象(Test实例对象)的钥匙,而钥匙是只有一份的,当有并发时,钥匙只能归一个线程使用,在使用过程中,其它线程需排队等候。从而达到控制test2方法同步代码块的访问

而test1中是没有加锁的,可进行并发处理,线程与线程之间同时执行也没有关系

也不知道有没有说清楚,没说清楚可评论区一起讨论~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值