[Java] Java并发中涉及到的显式锁
使用由JVM提供的java内置锁的时候,不需要通过Java代码显式地经过对象监视器进行锁的抢占和释放(例如调用某些java并发包或采用synchronized关键字)。
Java对象锁在竞争稍微激烈时会膨胀为重量级锁(基于对象的Mutex Lock),其线程阻塞和唤醒操作会在内核状态和用户态之间切换,导致性能急剧降低。
若想要实现一些高级锁功能,则需要显示使用锁,例如以下功能:
限时抢占:抢占锁时设置超时时长,防止线程无限等待。(记忆不太清晰,好像notify方法就有这功能)
中断抢占:抢锁线程处于阻塞状态时,可由外部线程给予抢锁线程中断信号将其唤醒并终止抢占过程。
多等待队列:为锁维持多个等待队列,以提高锁使用效率(如生成消费者队列)。
1.ReenrantLock
直接实现interface Lock
方法:
lock() # 抢占锁
tryLock() #非阻塞抢占锁,返回true或者false
tryLock(long time, TimeUnit unit) #限时抢占锁
2.ReentrantReadWriteLock 读写锁
可以获取写锁或者读锁。
读锁可被多线程抢占,写锁为排斥锁,读锁和写锁之间排斥。
可以在抢占写锁之后抢占读锁,以达到“锁降级”的效果。
3.StampedLock 印戳锁
在只有读的情况下,支持不加读锁直接进行读操作。仅在写操作之后才需要加读锁进行读操作。
其模式为:
悲观读锁
乐观读锁
写锁