JUC-Lock接口替代synchronized

JUC:

java.util.concurrent在并发编程中使用的工具类

Lock接口

java官方api中给其的解释:

  • Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements. They allow more flexible structuring, may have quite different properties, and may support multiple associated Condition objects.
  • 锁实现提供了比使用同步方法和语句可以获得的更广泛的锁操作。它们允许更灵活的结构,可能具有非常不同的属性,并且可能支持多个关联的条件对象。

相比于Synchronized的使用,Lock更加灵活和性能

在这里插入图片描述
api中的官方案例:
在这里插入图片描述

Lock接口的实现 ReentrantLock可重入锁

api中案例:
在这里插入图片描述
因为其也是实现Lock接口,所以在使用方法上差不多;Lock的实现类更多的是其锁的特性;

  • 可重入锁:A reentrant mutual exclusion Lock with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities.
  • 可重入互斥锁,但具有扩展功能。

使用Lock与synchronized差别:

经典案例:多线程卖票小程序

实现步骤:

  • 1:创建资源类
  • 2:在资源类创建同步方法/同步代码块

synchronized

资源类:

class Ticket{
    //30张票
    private  int number=30;
    public synchronized void sale(){

        synchronized (this){

        }

        if (number>0){
            System.out.println(Thread.currentThread().getName()
            +"\t 卖出"+number--+"号票;还剩下"+number);
        }
    }

}

使用ReentrantLock重入锁方式:

资源类:

class Ticket{
    //30张票
    private  int number=30;
    private Lock lock=new ReentrantLock();

//    Lock的实现:可重入锁类:ReentranLock
    public void sale(){
        lock.lock();
        try {
            if (number>0){
                System.out.println(Thread.currentThread().getName()
                +"\t 卖出"+number--+"号票;还剩下"+number);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

买票程序:

public class SaleTicket {
    /**
    *   :三个售票员 卖出三十张票
    *
    * @Author:LRC
    * @Date:11:19 下午 2020/7/2
    */
    public static void main(String[] args) throws Exception {
        Ticket ticket = new Ticket();
        //lambda表达式
        new Thread(()->{for (int i = 1; i <=40 ; i++) ticket.sale();},"AA").start();
        new Thread(()->{for (int i = 1; i <=40 ; i++) ticket.sale();},"BB").start();
        new Thread(()->{for (int i = 1; i <=40 ; i++) ticket.sale();},"CC").start();
}

运行:

(其实运行结果没有意义,因为每次的结果都不一样:
线程启动顺序并不是按代码顺序,因为线程启动是native方法,是看系统的调用)native也就是调用本地库的方法,所以线程的启动顺序不一定和代码顺序是一样的

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值