Java中的锁----Sky
1.1 Lock接口
Lock接口和syncchronized的区别?
Lock提供了与syncchronized关键字相似的功能,syncchronized:隐式获取释放锁;
Lock显示地获取和释放,可操作性,尝试非阻塞的获取锁,能被中断的获取锁,线程中断,异常抛出锁释放。还可以超时获取锁,
Lock lock = new ReentrantLock(); lock.lock(); lock.unlock();
Lock的API如下:void Lock() 获取锁;
lockInterruptibly():在锁的获取中可以中断当前线程;
Boolean tryLock() : 尝试非阻塞获取锁;
boolean tryLock(long time, TimeUnit unit): 超时获取锁;
unlock() 锁的释放;
Codition newCondition() 获取等待通知组件,该组件和当前的锁绑定,当前线程只有获得了锁,才能调用该组件的wait()方法,调用后,当前线程释放锁。
1.2 重入锁
重入锁:ReentrantLock,顾名思义支持重新进入的锁,支持一个线程对资源的重复加锁。除此之外,该锁还支持获取锁的公平和非公平性选择。
保证当一个线程重复获取锁时不会阻塞自己。
1.实现重新进入
1)线程再次获取锁:识别获取锁的线程,是否为当前占据锁的线程,是则再次成功获取;
2)锁的最终释放:获取n次,释放n次。直到最后一次释放为止,采用计数自减方式。
2.公平与非公平获取锁的区别
公平性:取决于时间先后顺序。airTryAcquire();时间顺序,锁切换次数大,开销大。
非公平性:刚释放的线程再次获取锁的几率大,会出现重复获取锁的情况。锁开销小,默认实现。可能会造成线程“饥饿”,但极少的线程切换,保证了足够大的吞吐量。
1.3 读写锁
排它锁:Mutex和reentrantLock,同一时刻只允许一个线程访问。
读写锁:同一时刻可允许多个读线程同时访问,但在写线程访问时,所以读线程和其他写线程均被阻塞。通过分离读锁和写锁,并发现高于其他排他锁。只需要在读操作获取读锁,写操作获取写锁。当写锁被获取到的时候,后续读操作都会被阻塞,写释放后,后续所有操作继续执行。
大多数读多于写,所以使用读写锁具有更好的并发性和吞吐量。
java读写锁的实现是:ReentrantReadWriteLock();
读写锁的接口与示例:
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
Lock r = rwl.readLock();
Lock w = rwl.writeLock();
读写操作时,先获取锁然后在释放,保证了每次写操作对所有的读写操作的可见性,简化了代码。
读写锁的获取和释放:
写锁:存在读锁,必先释放,否则写锁不能获取;
读锁:没有其他写线程访问时,读锁总能被获取。
锁降级:把持有的写锁,再获取到读锁,随后释放先前拥有写锁的过程。保证了数据的可见性。
1.4 LockSupport工具
LockSupport定义了一组以part开头的方法来阻塞当前线程,以及unpart()来唤醒一个被阻塞的线程。
part() ;park(long nanos); parkUntil(long deadline);unpark(Thread thread);具体详细的在这里不做明细介绍。
1.5 Condition接口

浙公网安备 33010602011771号