将synchronized()与ReentrantLock.lock()混合
在Java中, ReentrantLock.lock()
和ReetrantLock.unlock()
使用与ReetrantLock.unlock()
相同的锁定机制?
我的猜测是“不”,但我希望是错的。
例:
想象一下,线程1和线程2都可以访问:
ReentrantLock lock = new ReentrantLock();
线程1运行:
synchronized (lock) { // blah }
线程2运行:
lock.lock(); try { // blah } finally { lock.unlock(); }
假设线程1首先到达其部分,然后在线程1完成之前到达线程2:线程2将等待线程1离开synchronized()
块,还是继续运行?
不,即使线程1在同一个lock
synchronized
,线程2也可以lock()
。 这就是文档所说的内容:
请注意,Lock实例只是普通对象,它们本身可以用作synchronized语句中的目标。 获取Lock实例的监视器锁与调用该实例的任何lock()方法没有指定的关系。 为避免混淆,建议您不要以这种方式使用Lock实例,除非在他们自己的实现中。
这两种机制是不同的。 实施/绩效明智:
- 同步机制使用“内置于”JVM中的锁定机制; 底层机制受特定JVM实现的约束,但通常使用原始比较和设置操作 (CAS)指令的组合,用于没有争用锁的情况加上OS提供的底层锁定机制;
- 诸如ReentrantLock之类的锁类基本上是用纯Java编写的(通过Java 5中引入的库,它将CAS指令和线程去调度暴露给Java),因此在操作系统中更加标准化并且更可控(见下文)。
在某些情况下,显式锁可以更好地执行。 如果你看一下我在Java 5下执行的锁定机制的比较 ,你会看到在那个特定的测试中(多个线程访问一个数组),在“不公平”模式下配置的显式锁类(黄色和青色三角形)允许更多吞吐量比普通同步(紫色箭头)。
(我还应该说,在最新版本的Hotspot中,synchronized的性能得到了提升;在最新版本或其他情况下可能没有太多内容 – 这显然是在一个环境中的一个测试。)
function明智的:
- 同步机制提供最少的function(你可以锁定和解锁,锁定是一个全有或全无的操作,你更多地受制于OS编写者所决定的算法),尽管具有内置语法和一些监控的优势内置于JVM中;
- 显式锁类提供更多控制,特别是你可以指定一个“公平”锁定,锁定超时,如果你需要改变锁定的behiour覆盖……
为什么在Account类中使余额保持静态? 删除静电,它应该工作。
另外,对您的线程使用情况有疑问。 在TestMain中,您可以创建新线程并分配可运行的项目,如WithdrawRequests和DepositRequests。 但是,您再次在这些可运行的构造函数内创建新线程。 这将导致run方法执行两次!
- GSSexception:不支持/启用具有HMAC SHA1-96的加密类型AES256CTS模式
- 从CLI生成base64编码的哈希以匹配Java
- 将Solr xml文件解析为SolrInputDocument
- 如何在我自己的Project JAR中包含外部JAR
- 将多个String变量添加到ArrayList
- 为什么tesseract失败了这张图片?
- Amazon SES自定义标头List-Unsubscribe无效
- null类型的参数应该显式地转换为Class 以调用varargs方法
- 为什么要捕获InterruptedException来调用Thread.currentThread.interrupt()?