Java中的锁
- 锁(lock):在多线程环境中强制线程对资源进行互斥性质的访问。
- 锁粒度:
粒度粗的锁——锁的数量少,每个锁保护大量数据。单个进程访问时锁的开销少;多进程访问时性能较差,因为锁的竞争较大。
粒度细的锁——锁的数量多,每个锁保护的数据少。增加了锁的开销但减少了锁竞争。
数据库中锁的粒度:表锁、页锁、行锁、字段锁 - (广义概念)独享锁:同时只能被一个线程使用的锁
(广义概念)共享锁:可以被多个线程共享的锁 - 读写锁:读锁是共享锁,写锁是独享锁
读-读(可)、读-写(不可)、写-写(不可)
接口ReadWriteLock有两个实现类 readLock()和writeLock()分别对应读写 - 公平锁:多个线程申请使用一个锁,使用的顺序按照申请顺序排列。
非公平锁:多个线程获取锁的顺序不是按照申请的顺序,有可能后申请的线程优先获取锁。ReentrantLock默认是非公平锁,但可以通过构造函数控制是否公平;Synchronized是非公平锁,由于不像ReentrantLock一样通过AQS实现对锁的获取,使其不能改变是否公平,只能是非公平锁。 - 可重入锁:线程的外层方法获取了锁,在其内层方法也会自动获取锁,可以避免死锁。
Synchronized和ReentrantLock都是可重入锁。 - 乐观锁:认为不存在很多并发更新操作,不需要加锁。
悲观锁:认为存在很多并发更新操作,需要加锁 - 自旋锁:两个线程A、B申请同一个锁,A获得了锁,B不被挂起(阻塞,释放CPU资源),而是原地等待A执行完释放锁,再获得锁,自旋锁是一种非阻塞锁
- 偏向锁、轻量级锁、重量级锁