Java锁机制——隐式锁和显式锁的区别

概述

Java技术中的锁机制是高并发采用多线程编程中的非常重要一环,用于解决资源竞争问题。
Java 中的并发锁大致分为隐式锁和显式锁两种。隐式锁就是我们最常使用的 synchronized 关键字,显式锁主要包含两个接口:Lock 和 ReadWriteLock,主要实现类分别为 ReentrantLock 和 ReentrantReadWriteLock,这两个类都是基于 AQS(AbstractQueuedSynchronizer) 实现的。
CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术。简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替换当前变量的值。
很多地方把CAS也归于JAVA并发编程的锁机制。

隐式锁和显式锁的区别

层面不同

Synchronized:Java中的关键字,是由JVM来维护的,是JVM层面的锁;
Lock:是JDK5以后才出现的具体的类,使用lock是调用对应的API,是API层面的锁;
synchronized是底层是通过monitorenter进行加锁(底层是通过monitor对象来完成的,其中的wait/notify等方法也是依赖于monitor对象的。只有在同步块或者是同步方法中才可以调用wait/notify等方法的。因为只有在同步块或者是同步方法中,JVM才会调用monitory对象的);通过monitorexit来退出锁的。
而lock是通过调用对应的API方法来获取锁和释放锁的。Synchronized通过monitorenter完成锁的初始化和获取锁
在这里插入图片描述

使用方法不同

A.锁的释放

  • Synchronized直接作用于方法上,并且不需要开发者手动去释放锁,如果发生异常,JVM会通知线程释放锁
  • Lock需要先创建对象,并且手动释放锁,在使用规范中必须在finally中执行,且容易造成死锁。

B.锁的获取

  • Synchronized:线程1获得锁,线程2会一直等待
  • Lock:可以通过trylock来知道有没有获取锁,可以设置阻塞等待时间;可以通过readwritelock实现读写分离

C.中断响应

  • Lock支持用interrupt来中断等待
  • Synchronized不能响应中断;

D.调度机制

  • Synchronized:使用Object对象本身的wait 、notify、notifyAll调度机制
  • Lock可以使用Condition进行线程之间的调度

Synchronized的几种用法

  • 同步普通方法(锁实例对象)
    public synchronized void testOne(){
        System.out.println("同步普通方法(锁实例对象)");
    }
  • 同步静态方法(锁类本身)
    public synchronized static void testTwo(){
        System.out.println("同步静态方法(锁类本身)");
    }
  • 同步类(锁类本身)
    public void testThree(){
        synchronized(SynchronizedService.class){
            System.out.println("同步类(锁类本身)");
        }
        synchronized(this.getClass()){
            System.out.println("同步类(锁类本身)");
        }
    }
  • 同步this实例(锁实例对象)
    public void testFour(){
        synchronized(this){
            System.out.println("同步this实例(锁实例对象)");
        }
    }
  • 同步对象实例(锁实例对象)
    private Object object = new Object();
    public void testFive(){
        synchronized(object){
            System.out.println("同步对象实例(锁实例对象)");
        }
    }

锁类本身,该类所有的对象同一把锁。 实例对象仅限制当前线程,多线程不起作用;testFive中如果object是静态方法,不管多少个实例,只有一个线程可以获取到锁,没有static修饰就是当前实例。

E.锁机制的区别
Synchronized原始采用的是CPU悲观锁机制,即线程获得的是独占锁。独占锁意味着其他线程只能依靠阻塞来等待线程释放锁。而在CPU转换线程阻塞时会引起线程上下文切换,当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低。

而Lock用的是乐观锁方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。乐观锁实现的机制就是CAS操作(Compare and Swap)。我们可以进一步研究ReentrantLock的源代码,会发现其中比较重要的获得锁的一个方法是compareAndSetState。这里其实就是调用的CPU提供的特殊指令。

Synchronized有个性能优化的小课题

后续再说哈。。。。。。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值