Lock接口——JUC随记2
创始人
2025-05-29 19:05:27

1、synchronized

1.1、synchronized的三种应用方式

一. 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁。
二. 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁。
三. 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象。

1.2、synchronized的字节码指令

synchronized同步块使用了monitorenter和monitorexit指令实现同步,这两个指令,本质上都是对一个对象的监视器(monitor)进行获取,这个过程是排他的,也就是说同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。
  线程执行到monitorenter指令时,会尝试获取对象所对应的monitor所有权,也就是尝试获取对象的锁,而执行monitorexit,就是释放monitor的所有权。

1.3多线程编程的简单实现

第一步:创建一个资源类
第二步:创建多个线程,调用资源类的方法
例如:

public class SaleTicket {public static void main(String[] args) {//第二步:创建多个线程,调用资源类的方法Ticket ticket = new Ticket();new Thread(new Runnable() {@Overridepublic void run() {for(int i=0;i<40;i++){ticket.sale();}}},"ThreadA").start();new Thread(new Runnable() {@Overridepublic void run() {for(int i=0;i<40;i++){ticket.sale();}}},"ThreadB").start();new Thread(new Runnable() {@Overridepublic void run() {for(int i=0;i<40;i++){ticket.sale();}}},"ThreadC").start();}
}
//第一步:创建一个资源类
class  Ticket{private int number=30;public synchronized void sale(){if(number>0){System.out.println(Thread.currentThread().getName()+":卖出第"+number--+"张票,剩下"+number+"张票");}}
}

运行结果:
在这里插入图片描述

2、Lock接口

2.1、定义

Lock锁实现提供了比使用同步方法和语句可以获得的更广泛的锁操作。它们允许更灵活的结构,可能具有非常不同的属性,并且可能支持多个关联的条件对
象。Lock提供了比synchronized更多的功能。

2.2、Lock与Synchronized的区别

  1. Lock 是-个接口,而synchronized是Java中的关键字, synchronized是内
    置的语言实现;
  2. synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock0去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
  3. Lock 可以让等待锁的线程响应中断,而synchronized却不行,使用
    synchronized时,等待的线程会一直等待 下去,不能够响应中断;
  4. 通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
  5. Lock 可以提高多个线程进行读操作的效率。在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争) , 此时Lock的性能要远远优于synchronized。

2.3、示例

import java.util.concurrent.locks.ReentrantLock;//创建多个线程调用资源类的方法
public class LockSaleTicket {public static void main(String[] args) {LTicket lTicket = new LTicket();new Thread(()->{lTicket.sale();},"线程A").start();new Thread(()->{for (int i = 0; i <30 ; i++) {lTicket.sale();}},"线程B").start();new Thread(()->{lTicket.sale();},"线程C").start();}
}
//第一步:创建一个资源类
class LTicket{int number=30;private final ReentrantLock lock =new ReentrantLock();public void sale(){//上锁lock.lock();try{//判断是否有票if(number>0){System.out.println(Thread.currentThread().getName()+":卖出第"+number--+"张票,剩下"+number+"张票");}}finally {//解锁lock.unlock();}}
}

在这里插入图片描述

相关内容

热门资讯

cad打印线条粗细设置 cad... 004-线型(下)打印样式设置和线型文件使用一、线宽设置方法制图规范里边的线宽要求,我们已经定义好,...
荼蘼什么意思 岁月缱绻葳蕤生香... 感谢作者【辰夕】的原创独家授权分享编辑整理:【多肉植物百科】百科君坐标:云南 曲靖春而至,季节流转,...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...