Java多线程中Java锁的那些事儿

Java多线程开发中,如果涉及到共享资源操作场景,那就必不可少要和Java锁打交道。

Java中的锁机制主要分为 LockSynchronized,本文主要分析Java 锁机制的使用和实现原理,按照Java锁使用、JDK中锁实现、系统层锁实现的顺序来进行分析,话不多说,let's go~

Java锁使用

在Lock接口出现之前,Java程序是靠 synchronized 关键字实现锁功能的,而 Java SE 5之后,并发包中新增了 Lock 接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功能,只是在使用时需要显式地获取和释放锁。虽然它缺少了(通过 synchronized 块或者方法)隐式获取释放锁的便捷性,但是却拥有了锁获取与释放的可操作性、可中断的获取锁以及超时获取锁等多种synchronized 关键字所不具备的同步特性。

Java锁使用示例:

Lock lock = new ReentrantLock();  
lock.lock();  
try {  
    // ..
} finally {
    lock.unlock();
}

注意:在finally块中释放锁,目的是保证在获取到锁之后,最终能够被释放。不要将获取锁的过程写在 try 块中,因为如果在获取锁(自定义锁的实现)时发生了异常,异常抛出的同时,会提前进行unlock导致IllegalMonitorStateException异常。

Lock 相较于 Synchronized 优势如下:

  • 可中断获取锁:使用 synchronized 关键字获取锁的时候,如果线程没有获取到被阻塞了,那么这个时候该线程是不响应中断(interrupt)的,而使用 Lock.lockInterruptibly() 获取锁时被中断,线程将抛出中断异常。
  • 可非阻塞获取锁:使用 synchronized 关键字获取锁时,如果没有成功获取,只有被阻塞,而使用 Lock.tryLock()获取锁时,如果没有获取成功也不会阻塞而是直接返回false。
  • 可限定获取锁的超时时间:使用 Lock.tryLock(long time, TimeUnit unit)
  • 同一个所对象上可以有多个等待队列(Conditin,类似于 Object.wait() ,支持公平锁模式)。

你可能感兴趣的:(Java多线程中Java锁的那些事儿)