Lock接口解析

锁是用来控制多个线程访问共享资源的方式,锁可以防止多个线程同时访问共享资源,提供对共享资源的独占式访问。一次只能有一个线程额可以获得锁,对共享资源的访问首先都要获得锁才可以(但是有些锁允许多个线程并发的访问共享资源,比如读写锁)Java提供了synchronized(同步锁)来实现锁的功能,在后来的版本中的并发包中加入了Lock接口以及他的实现类实现锁的功能。提供了和synchronized类似的同步功能,只是在使用的时候需要显示的获取和释放锁。

使用synchronized关键字获得锁和释放锁显然更容易些,不用我们去编程实现,并且还可以避免编程上的错误,一定程度上固化了过程,先获得再释放,虽然简化了同步的管理,但是灵活性和扩展性没有显示的获取和释放好。Lock和他的实现类拥有了锁获取和释放的可操作性、可中断的获取锁以及超时获取锁。


例如以下场景:先获得锁A,然后再获得锁B,当B获得后,释放锁A同时获得锁C,当锁C获得后,再释放B同时获得锁D。

以上的例子如果使用synchronized很难容易实现,使用synchronized获得多个锁的时候,他们必须以相反的顺序释放。

Lock lock = new ...; 
lock.lock(); 
try { 
    // 访问受此锁定保护的资源 
} finally { 
    lock.unlock(); 
} 
  • 当在不同范围内发生锁定和解锁时,必须注意确保在锁定时执行的所有代码由try-finally或try-catch保护,以确保在必要时释放锁定
  • 在finally代码块中释放锁,目的是保证在获取到锁之后,最终能够被释放。
  • 不要将获得锁的代码放在try块中,因为如果在获得锁时发生了异常,异常抛出的同时,也会导致锁的无故释放。

Lock提供了和synchronized关键字不具备的特点如下:

特性 描述
尝试非阻塞的获取锁 当前线程获取锁,如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁
能被中断的获得锁 与synchronized不同,获取到的锁的线程能够响应中断,当获取到锁的线程被中断时,中断异常将会抛出,同时锁会被释放
超时获得锁 在指定的截至时间之前获取锁,如果截至时间到了仍旧无法获取锁,则返回

参考摘抄:《Java并发编程的艺术》

猜你喜欢

转载自blog.csdn.net/qq_38663729/article/details/79776391