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();}}
}

在这里插入图片描述

相关内容

热门资讯

世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...