Java并发编程深入学习讲解.doc

  1. 1、本文档共10页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Java并发编程深入学习——Lock锁 Lock锁介绍 ??在Java 5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile。Java 5.0 增加了一种新的机制:ReentrantLock.它并不是一种替代内置加锁的方法,而是当内置加锁机制不适用时,作为一种可选择的高级功能。 Lock接口 Lock接口位于java.util.concurrent.locks包中,它定义了一组抽象的加锁操作。 public interface Lock { //获取锁 void lock(); // 如果当前线程未被中断,则获取锁 void lockInterruptibly() throws InterruptedException; //仅在调用时锁为空闲状态才获取该锁 //如果锁可用,则获取锁,并立即返回值 true。如果锁不可用,则此方法将立即返回值 false boolean tryLock(); //如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁 boolean tryLock(long time, TimeUnit unit) throws InterruptedException; //释放锁 void unlock(); //返回绑定到此 Lock 实例的新 Condition 实例 Condition newCondition(); } ??ReetrantLock 实现了Lock接口,并提供了与synchronized相同的互斥性和内存可见性,在获取ReentrantLock时,有着与进入同步代码块相同的内存语义,在释放ReentrantLock时,同样有着与退出同步代码块相同的内存语义。 lock锁与synchronized锁对比 为什么要创建一种与内置锁如此相似的新加锁机制?在大多数情况下,内置锁都能很好地工作,但在功能上存在一些局限性。 内置锁无法中断一个正在等待获取锁的线程,或者无法在请求获取一个锁时无限地等待下去。 内置锁必须在获取该锁的代码块中释放,这虽然简化了编码工作,并且与异常处理操作实现了很好的交互,但却无法实现非阻塞结构的加锁规则。 所以需要一种更加灵活的加锁机制,lock锁便应运而生。 Lock锁的标准使用形式如下: Lock lock = new ReentrantLock(); if (lock.tryLock()) {//尝试获取锁 try { //更新对象状态 //捕获异常,并在必要时恢复不变性条件 } finally { lock.unlock();//注意要记得释放锁 } } else { // 获取锁失败执行其他操作 } 如果没有使用finally来释放Lock,那么程序出错时,将很难追踪到最初发生错误的位置,因为没有记录应该释放锁的位置和时间。 这一点也是ReetrantLock不能完全替代synchronized的原因,因为它更加危险,程序并没有自动清除锁的机制,使用起来需要格外小心。 锁的分类 1.可重入锁 ??当某一个线程请求一个由其他线程持有的锁时,发去请求的线程就会阻塞。由于内置锁可重入特性的存在,如果某个线程视图获得一个已经由它自己持有的锁,那么这个请求却会成功。 ??如果锁具备可重入性,则称作为可重入锁。.像synchronized和ReentrantLock都是可重入锁,重入性表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。 重入锁的实现机制如下: ??为每个锁关联一个获取计数值和一个所有者线程。当计数器为0时这个锁被认为没有被任何线程持有。当线程请求一个未被持有的锁时,JVM将记下锁的持有者,并且将获取计数器置为1。如果同一个线程再次获取这个锁,计数器将递增,而当线程退出同步代码块时,计数器会相应地递减。当计数器为0时,这个锁将被释放。   可举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。   看下面这段代码就明白了: class MyClass { public synchronized void method1() { method2(); } public synchronized void

文档评论(0)

shuwkb + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档