显式锁与隐式锁的区别

显式锁与隐式锁的区别

解决的方法 格式 描述
同步代码块(关键字) synchronized(锁对象){} 隐式锁,多个线程的锁对象必须唯一
同步方法(修饰符) synchronized 返回类型 方法名(){} 隐式锁,谁调用该方法谁就是锁对象
显示锁 ReentrantLock类的lock()/unlock()方法 显式锁,由程序员决定在哪开启/关闭锁

一、构成不同

Sync 和 Lock 的出身(原始的构成)不同:

  • Sync:Java中的关键字,是由JVM来维护的。是JVM层面的锁。

  • Lock:是JDK5以后才出现的具体的类。使用 Lock 是调用对应的API。是API层面的锁。

  • Sync 底层是通过 monitorenter 进行加锁(底层是通过 monitor 对象来完成的,其中的wait/notify等方法也是依赖于 monitor 对象的。只有在同步代码块或者同步方法中才可以调用wait/notify等方法。因为只有在同步代码块或者是同步方法中,JVM才会调用 monitory 对象);通过 monitorexit 来退出锁

  • 而 Lock 是通过调用对应的API方法来获取锁和释放锁。

二、使用方法不同

Sync是隐式锁;Lock是显示锁。

所谓的显示和隐式就是在使用的时候,使用者要不要手动写代码去获取锁和释放锁。

  • 在使用sync关键字的时候,程序能够自动获取锁和释放锁。那是因为当sync代码块执行完成之后,系统会自动的让程序释放占用的锁。Sync是由系统维护的,如果非逻辑问题的话,是不会出现死锁的。
  • 在使用lock的时候,我们使用者需要手动的获取和释放锁。如果没有释放锁,就有可能导致出现死锁的现象。手动获取锁方法:lock();释放锁:unlock()

三、等待是否可中断

Sync是不可中断的。除非抛出异常或者正常运行完成。

Lock是可以中断的。中断方式:

  1. 调用设置超时方法tryLock(long timeout ,timeUnit unit)
  2. 调用lockInterruptibly()放到代码块中,然后调用interrupt()方法可以中断

四、加锁的时候是否公平

Sync:非公平锁。

Lock:两者都可以。默认是非公平锁,在其构造方法的时候可以传入Boolean值(true:公平锁;false:非公平锁)

五、锁绑定多个条件来condition

Sync:没有。要么随机唤醒一个线程;要么是唤醒所有等待的线程。

Lock:用来实现分组唤醒需要唤醒的线程,可以精确的唤醒,而不是像sync那样,不能精确唤醒线程。

你可能感兴趣的:(Java,java,并发编程)