当前位置: 首页 > news >正文

jdk-Lock类的翻译

1. Lock类的说明

  1. Lock 的实现类提供了比synchronized方法和语句的更多的扩展的锁操作
    他们允许更加灵活多变的结构,可能有相当不同的属性,可能支持多种的关联Condition对象
  2. 锁是一种工具,用于控制多个线程对共享资源的访问。通常,锁提供对共享资源的独占访问(exclusive access):一次只有一个线程可以获取锁,并且所有对共享资源的访问都要求首先获取锁。然而,某些锁可能允许对共享资源的并发访问,例如ReadWriteLock中的读锁。
  3. 使用synchronized方法或语句提供了对每个对象关联的隐式监视器锁(implicit monitor )的访问,但强制所有的锁获取和释放都必须以块结构的方式进行:当获取多个锁时,它们必须按相反的顺序释放,并且所有锁都必须在获取它们的同一词法范围内释放。
  4. 虽然对于synchronized方法和语句的范围机制使得使用监视器锁编程变得更加容易,并且有助于避免许多涉及锁的常见编程错误,但在某些情况下,你需要以更加灵活的方式来处理锁。例如,有些算法用于遍历并发访问的数据结构时,需要使用“hand-over-hand”或“chain locking”的方式:你先获取节点A的锁,然后是节点B的锁,接着释放A并获取C的锁,再释放B并获取D的锁,依此类推。实现Lock接口的类通过允许在不同的范围内获取和释放锁,以及允许多个锁以任意顺序获取和释放,从而支持使用这样的技术。
  5. 随着灵活性的增加,也带来了额外的责任。块结构锁定的缺失意味着不会像synchronized方法和语句那样自动释放锁。在大多数情况下,应该使用以下模式
    Lock l = ...;
    l.lock();try {// access the resource protected by this lock
    } finally {l.unlock();
    }}
    
    当锁的获取和释放发生在不同的范围内时,必须小心确保所有在持有锁期间执行的代码都受到try-finally或try-catch的保护,以确保在必要时能够释放锁
    6. Lock接口的实现通过提供以下功能,比使用synchronized方法和语句提供了更多的灵活性:非阻塞尝试获取锁tryLock(), 可以被中断的锁获取尝试 lockInterruptibly,可以设置超时时间的锁获取尝试tryLock(long, TimeUnit).
    7. Lock类还可以提供与隐式监视器锁非常不同的行为和语义,例如保证的顺序、不可重入的使用或死锁检测。如果某个实现提供了这种专门的语义,那么该实现必须在文档中说明这些语义
    8. 请注意,Lock实例只是普通的对象,它们自身可以用作synchronized语句中的目标。获取Lock实例的监视器锁与调用该实例的任何lock方法之间没有明确的关系。为了避免混淆,建议你永远不要以这种方式使用Lock实例,除非是在它们自己的实现中。
    9. 除非另有说明,对任何参数传递null值都将导致抛出NullPointerException

Memory Synchronization

  1. 所有Lock实现必须强制执行与内置监视器锁相同的内存同步语义,如《Java语言规范》第17章所述:
    • 成功的lock操作具有与成功的Lock操作相同的内存同步效果。
    • 成功的unlock操作具有与成功的Unlock操作相同的内存同步效果。
    • 不成功的锁定和解锁操作,以及可重入的锁定/解锁操作,不需要任何内存同步效果

Implementation Considerations

  1. 三种形式的锁获取(可中断的、不可中断的和定时的)可能在性能特性、顺序保证或其他实现质量方面有所不同。此外,中断正在进行(ongoing)的锁获取的能力可能在给定的Lock类中不可用。因此,实现并不需要为所有三种形式的锁获取定义完全相同的保证或语义,也不需要支持对正在进行的锁获取的中断。实现必须清楚地记录每种锁定方法提供的语义和保证。它还必须遵守本接口中定义的中断语义,即在支持锁获取中断的情况下,要么完全支持,要么仅在方法入口处支持
  2. 由于中断通常意味着取消,并且中断检查往往不频繁,因此实现可以优先响应中断而不是正常的方法返回。即使可以证明中断发生在另一个动作可能已经解除线程阻塞之后,这也是正确的。实现应该记录这种行为
  3. 参考:ReentrantLock, Condition,ReadWriteLock , 17.4 Memory Model
public interface Lock {/*** 获取锁 Acquires the lock.* 如果锁不可用,则当前线程将被禁用以进行线程调度,并保持休眠(lies dormant)状态,直到获取到锁为止。* * 实现考虑:* 一个Lock实现可能能够检测到锁的错误(erroneous )使用,* 例如可能导致死锁的调用,并在这种情况下抛出一个(未检查的)异常。* 这种情形以及异常类型必须由该Lock实现文档说明。**/void lock();/*** * 如果当前线程没有被中断,则获取锁** 如果锁可用,则立即获取并返回。* 如果锁不可用,则当前线程将被禁用以进行线程调度,并保持休眠状态,直到以下两种情况之一发生: * 1. 当前线程获取到锁;或* 2. 其他线程中断了当前线程,并且支持中断锁的获取。* * 如果当前线程* 1. 如果在进入此方法时当前线程的interrupted 状态已被设置,或者* 2. 在获取锁的过程中当前线程被中断,并且支持中断锁的获取* 则抛出InterruptedException,并且当前线程的中断状态将被清除** 实现考虑:* 1. 在某些实现中,中断锁的获取可能不可行,即使可行也可能是一个昂贵的操作。* 程序员应该意识到这种情况的可能性。 实现应该记录这种情况。* 2. 实现可以优先响应中断而不是正常的方法返回。* 3.  一个Lock实现可能能够检测到锁的错误使用,例如可能导致死锁的调用,并在这种情况下抛出一个(未检查的)异常。* 这种情形以及异常类型必须由该Lock实现文档说明。* * @throws InterruptedException 如果当前线程在获取锁的过程中(并且支持中断锁的获取)被interrupted*/void lockInterruptibly() throws InterruptedException;/*** 仅在调用时锁是空闲的情况下获取锁** 如果锁可用,则立即获取并返回true。* 如果锁不可用,则立即返回false。* 典型用法:* * Lock lock = ...;* if (lock.tryLock()) {*   try {*     // manipulate protected state*   } finally {*     lock.unlock();*   }* } else {*   // perform alternative actions* }}* 这种用法确保了如果锁被成功获取,则会在finally块中释放锁;如果没有获取到锁,则不会尝试释放锁。* * @return 如果锁被成功获取,返回true。否则返回false。*/boolean tryLock();/*** 在给定的等待时间内获取锁(如果锁是空闲的并且当前线程没有被中断)* 如果锁可用,该方法会立即返回true。* 如果锁不可用,则当前线程将变为不可调度状态并进入休眠,直到以下三种情况之一发生: * 1. 当前线程获取到锁;* 2. 其他线程中断了当前线程,并且支持中断锁的获取;* 3. 指定的等待时间已过。* 如果锁被成功获取,则返回true** 如果当前线程: * 在调用此方法时已经设置了中断状态;或者* 在获取锁的过程中被中断,并且支持中断锁的获取, 则抛出InterruptedException异常,并清除当前线程的中断状态。* 如果指定的等待时间已过,* 则返回false。* * 如果等待时间小于或等于零,该方法不会等待。* * 实现考虑:* 1. 在某些实现中,中断锁的获取可能不可行,即使可行也可能是一个昂贵的操作。* 程序员应该意识到这种情况的可能性。 实现应该记录这种情况。* 2. 实现可以优先响应中断而不是正常的方法返回或报告超时。* 3.  一个Lock实现可能能够检测到锁的错误使用,例如可能导致死锁的调用,并在这种情况下抛出一个(未检查的)异常。* 这种情形以及异常类型必须由该Lock实现文档说明。*** @param time 等待锁的最大时间* @param unit time参数的时间单位。* @return 如果锁被成功获取,返回true。如果等待时间已过而未能获取到锁,返回false。** @throws InterruptedException 如果当前线程在获取锁的过程中(并且支持中断锁的获取)被interrupted*/boolean tryLock(long time, TimeUnit unit) throws InterruptedException;/*** 释放锁* 实现考虑: * Lock实现通常会对哪个线程可以释放锁进行限制(通常是只有锁的持有者才能释放它),* 如果违反了这些限制,可能会抛出一个未检查的异常。* 任何限制和异常类型都必须由该Lock实现进行文档说明。* */void unlock();/*** 返回一个新的与当前Lock实例绑定的Condition实例** 在等待条件之前,当前线程必须持有锁。* * 调用Condition#await()方法将原子性地在等待前释放锁,并在等待返回前重新获取锁。** 实现考虑: * Condition实例的确切操作取决于Lock的实现,并且必须由该实现进行文档说明。** @return 返回一个新的与当前Lock实例关联的Condition实例* @throws 如果这个Lock实现不支持条件,则抛出UnsupportedOperationException。*/Condition newCondition();
}

http://www.mrgr.cn/news/69131.html

相关文章:

  • 开放式耳机如何选择?五款千万不能错过的开放式耳机机型推荐
  • 劫持微信聊天记录并分析还原 —— 访问数据库并查看聊天记录(五)
  • 微信小程序weui安装实战:NPM包最佳实践指南,快速构建UI组件库
  • 【CSP】爆零的独特姿势
  • PNG图片批量压缩exe工具+功能纯净+不改变原始尺寸
  • 在使用element中的抽屉<el-drawer>页签<el-tabs/>组合时,echarts图表宽度显示异常问题
  • 分布式和并发模型的比较和讨论记录
  • [Linux] 进程等待 | 进程替换
  • Codeforces Round 984 (Div. 3)
  • ODOO学习笔记(3):Odoo和Django的区别是什么?
  • Docker的轻量级可视化工具Portainer
  • ssm077铁岭河医院医患管理系统+vue(论文+源码)_kaic
  • 特殊符号大全
  • 驱动开发系列27 - Linux Kernel 内核调试环境配置
  • 【softmax基础】如何使用什么时候使用
  • Python:scipy.signal.find_peaks 查找数据内的波峰波谷
  • 从0开始linux(25)——链接文件
  • c程序编译预处理命令那些事
  • 电工领域文档规范引用格式说明
  • 装杯 之 Linux指令【补充篇】