JAVA并发编程-LOCK锁

Lock接口有3个实现它的类:
ReentrantLock                                       重入锁
ReetrantReadWriteLock.ReadLock       读锁
ReetrantReadWriteLock.WriteLock      写锁

代码示例:
Lock lock = new ReentrantLock(); //默认使用非公平锁,如果要使用公平锁,需要传入参数true
  ........
  lock.lock();
  try {
       //更新对象的状态
      //捕获异常,必要时恢复到原来的不变约束
     //如果有return语句,放在这里
} finally {
         lock.unlock();        //锁必须在finally块中释放
}


两种锁机制的底层的实现策略

synchronized 互斥同步最主要的问题: 进行线程阻塞和唤醒所带来的性能问题, 一种悲观的并发策略, 线程获得的是独占锁。独占锁意味着其他线程只能依靠阻塞来等待线程释放锁
CPU转换线程阻塞时会引起线程上下文切换,当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低



ReetrantLock 冲突检测的乐观并发策略:
如果没有其他线程争用共享数据,那操作就成功了,如果共享数据被争用,产生了冲突,
那就再进行其他的补偿措施(最常见的补偿措施就是不断地重拾,直到试成功为止)
这种乐观的并发策略的许多实现都不需要把线程挂起,因此这种同步被称为非阻塞同步


LOCK用途:

1    等待可中断:当持有锁的线程长期不释放锁时,正在等待的线程可以选择放弃等待,改为处理其他事情

2、可实现公平锁:多个线程在等待同一个锁时,必须按照申请锁的时间顺序排队等待,
而非公平锁则不保证这点,在锁释放时,任何一个等待锁的线程都有机会获得锁              
公平锁: ReentrantLock(ture)

3、锁可以绑定多个条件:ReentrantLock对象可以同时绑定多个Condition对象(名曰:条件变量或条件队列)
只需要多次调用newCondition()方法即可。而且我们还可以通过绑定Condition对象来判断当前线程通知的是哪些线程


可中断锁

ReetrantLock有两种锁:忽略中断锁和响应中断锁。
忽略中断锁与synchronized实现的互斥锁一样,不能响应中断,
而响应中断锁可以响应中断

ReentrantLock lock = new ReentrantLock();
...........
lock.lockInterruptibly(); //获取响应中断锁
try {
       //更新对象的状态
       //捕获异常,必要时恢复到原来的不变约束
       //如果有return语句,放在这里
} finally {
     lock.unlock();        //锁必须在finally块中释放
}

synchronized获取的互斥锁不仅互斥读写操作、写写操作,还互斥读读操作
ReadWriteLock rwl = new ReentrantReadWriteLock();   
rwl.writeLock().lock()  //获取写锁
rwl.readLock().lock()  //获取读锁
用读锁来锁定读操作,用写锁来锁定写操作,
这样写操作和写操作之间会互斥, 读操作和写操作之间会互斥,但读操作和读操作就不会互斥





提倡在synchronized能实现需求的情况下,优先考虑使用synchronized来进行同步。

使用 ReentrantLock的最佳时机:

当你需要以下高级特性时,才应该使用:可定时的、可轮询的与可中断的锁获取操作,公平队列,或者非块结构的锁。否则,请使用synchronized。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值