Java并发包中的锁机制如何为?

摘要:JAVA中主要锁 synchronized Reentrantlock ReentrantReadWriteLock 问题引入 为什么需要锁? 为什么JAVA有了synchronize还需要Reentrantlock和ReentrantRe
JAVA中主要锁 synchronized Reentrantlock ReentrantReadWriteLock 问题引入 为什么需要锁? 为什么JAVA有了synchronize还需要Reentrantlock和ReentrantReadWriteLock? synchronize和lock分别怎么实现同步快(原子性,一致性,禁重排序)? synchronize和lock分别怎么实现锁的优化,可重入锁,偏向锁? lock如何实现公平锁(synchronize是非公平锁)? 为什么需要锁? 目的: 锁的目的是防止资源的竞争,主要从原子性(一致性),可见性,防止处理重排序三个方面来处理,volatile满足了后面两个特性,JAVA从两方面来实现锁 为什么JAVA有了synchronize还需要Reentrantlock和ReentrantReadWriteLock? synchronized与ReentrantLock,使用上看区别 1,synchronize在获取锁阻塞的时候是不能打断的 2, synchronize无超时机制,阻塞了的话只能一直阻塞造成死锁 3,synchronize只能notify,wait,如果需要两个或以上条件就不能用了,如: JAVA阻塞队列的实现,需要用是否为空和是否已满两个条件来阻塞线程 看lock相关的API就知道, 主要就是解决这几个问题 方法名称 描述 lock 获取锁,如果锁无法获取,那么当前的线程就变为不可被调度,直到锁被获取到 lockInterruptibly 获取锁,除非当前线程被中断。如果获取到了锁,那么立即返回,如果获取不到,那么当前线程变得不可被调度,一直休眠直到下面两件事情发生:1、当前线程获取到了锁 2、其他的线程中断了当前的线程 tryLock 如果调用的时候能够获取锁,那么就获取锁并且返回true,如果当前的锁无法获取到,那么这个方法会立刻返回false tryLcok(long time,TimeUnit unit) 在指定时间内尝试获取锁如果可以获取锁,那么获取锁并且返回true,如果当前的锁无法获取,那么当前的线程变得不可被调度,直到下面三件事之一发生:1、当前线程获取到了锁 2、当前线程被其他线程中断 3、指定的等待时间到了 unlock 释放当前线程占用的锁 newCondition 返回一个与当前的锁关联的条件变量。在使用这个条件变量之前,当前线程必须占用锁。调用Condition的await方法,会在等待之前原子地释放锁,并在等待被唤醒后原子的获取锁 那ReentrantReadWriteLock呢? 读写锁用于读多写少的情况,即当一条线程获取写锁后,后面的读锁都被阻塞,等待获取写锁的线程完成释放。 场景,如本地缓存失效,当需要去DB拿数据进行写入的操作,需要阻塞其它读的操作. 当然,读写锁也是可以基于notifyAll和wait实现 需要注意的是 如果无写锁,读是不阻塞, 持有读锁后,不能直接调用写锁的lock方法 ,否则会造成死锁 synchronize和lock分别怎么实现同步快(原子性,一致性,禁重排序)? synchronized锁 实现依赖 原子性,可见性和重排序都是依靠指令。
阅读全文