Synchronized的实现

本文详细解析了Java中的synchronized关键字,包括其在字节码层面的表现,如何实现锁的获取与释放。synchronized可以锁定对象实例或类,对于非静态方法,每个对象拥有独立的锁,不同对象可以并行执行;而对于静态方法,锁住的是类,所有实例共享一把锁。此外,synchronized具备可重入特性,避免了死锁问题。示例代码展示了可重入锁的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Synchronized

1.1 加了synchronized的字节码指令和java源代码

 synchronized(new Object()){            int a = 1;int b = 2;        System.out.println(add(a,b));       }

由上图:被Synchronized修饰过的代码块,会生成monitorenter(监视器)字节码指令和monitorexit(监视器退出)字节码指令,当虚拟机执行到监视器指令的时候,就要去尝试去获取这个对象的锁,如果这个对象没有锁定,或者是当前线程已经获取了这个对象的锁(因为是可重入锁),就把锁的计数器+1,如果执行到监视器退出指令时候,就把锁的计数器-1。当计数器变为0的时候,就相当于这把锁被释放了,大家可以竞争。

1.2 Synchronized到底锁主了什么?

1.Synchronized(Object、this)这样指定了对象的锁的就是这个对象

2.在非静态方法上加上Synchronized相当于每个对象都有一把单独的锁

,假设创建对象p1,p2 如果p1执行了add方法占用了锁,但是占用的只是p1对象的锁,在另外一个线程中不影响p2继续执行add方法。

 public synchronized int add(int a,int b)

3.在静态方法上加锁

相当于锁住了这个类,所有的实例共享一把锁,p1执行add方法占用了锁,在另外一个线程p2如果也想要add方法,执行同样需要等待

 public synchronized static int add(int a,int b)

1.3可重入的特征

Synchronized是一个可重入锁,为了解决锁死自己的情况,来看示例:

  Object o = new Object();
       synchronized (o){ //计数器+1变为1
           synchronized (o){//计数器+1变为2
               System.out.println("执行么? ");
           }//计数器-1变为1
       }//计数器-1变为0 此时别的线程能够抢占

第一个synchronized已经占用到o这把锁了,第二个还能拿么,答案是可以的,不然很容易锁死。代码正常执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值