概述
Java的Lock锁和synchronized关键字的区别及其使用
一、synchronized关键字和Lock的区别以及优缺点
- 当执行完代码块中的代码,释放锁;
- 当代码抛出异常,释放锁;
- 当调用锁的wait方法,释放锁;
以上三种情况便可以完全的帮我们解决线程同步的问题,为什么还要引入Lock呢?同样,synchronized关键字也有三种局限性:
- synchronized关键字无法响应中断,如果线程未获得锁,便会一直地尝试去获得锁,不会响应中断,lock锁的lockInterruptibly()方法能让线程响应中断,同时tryLock可以加入时间参数,若一定时间内未获得锁便返回,很灵活;
- synchronized关键字无法读写分离,在多个读线程访问临界资源时,是不需要同步的,但是synchronized关键字通通都给同步了,会导致效率很慢,Lock提供读写锁,实现读写分离;
- synchronized关键字无法知道线程是否获得锁;
以上为synchronized的局限性,但是Lock也有他的缺点,Lock需要显式的释放锁,否则会造成死锁。
接下来我们之上而下地看看Lock的类和接口吧...
二、Lock接口
Lock接口是最顶层的接口,提供的方法主要有这么几个:
1、lock()
lock()方法会尝试的获取锁,如果锁已经被其他线程给获取了,就会阻塞等待,需要注意的是,lock()需要显式地释放锁,如果发生异常也不会释放锁,所以很容易发生死锁,通常需要在finally中释放锁,保证锁一定被释放。
2、tryLock()
tryLock()会非阻塞地去获取锁,若获得锁则返回true,否则返回false,可以加入时间长度和时间单位参数,给线程一段等待的时间。
3、lockInterruptibly()
三、ReentrantLock类
四、ReentrantReadWriteLock类
五、Condition类
Condition类提供wait()和notify()方法的替代,由锁实现,await()方法替代wait()方法,signal()和signalAll()方法替代notify()和notifyAll()方法,不同的是,一个Lock可以有多个Condition,而一个synchronized关键字只能有一个阻塞队列。
如,在生产者消费者模型中,可以有两个Condition,一个用于提示仓库已满,一个用于提示仓库已空。
以上便是Lock的全部内容,接下来介绍几种锁的概念:
六、锁的概念
1、重入锁
上文已经提及,不赘述。
2、可中断锁
顾名思义,是可以响应中断的锁,synchronized关键字是非可中断锁,Lock是可中断锁。
3、公平锁
公平锁的含义就是,当多个线程等待同一个锁的时候,等待时间最久的线程获得即将释放的锁,即为公平,synchronized关键字是非公平的,Lock默认情况也是非公平的,但是可以在构造的时候,手动设置成公平锁。
4、读写锁
将读和写分为两个锁,使多个读线程不会相互等待。
5、乐观锁和悲观锁
两者都是顾名思义:乐观锁,就是一种很乐观的想法,认为自己在操作数据的时候,不会有其他任何的更新操作,所以在取数据的时候不加锁,只在提交更新的时候判断是否有人动过该数据,如使用版本号等机制。
悲观锁,很悲观地认为在自己操作数据的时候,一定会有人操作数据,所以在取数据阶段就加锁,直到更新结束释放锁。数据库中的行锁,表锁,读锁,写锁都是悲观锁的实现。
如此一分析,显然在读多写少的环境下,乐观锁会比较奏效,因为当并发量很大,乐观锁,便会不停地retry,降低效率。
最后
以上就是义气哑铃为你收集整理的Java的Lock锁和synchronized关键字的区别及其使用Java的Lock锁和synchronized关键字的区别及其使用的全部内容,希望文章能够帮你解决Java的Lock锁和synchronized关键字的区别及其使用Java的Lock锁和synchronized关键字的区别及其使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复