【翻译十八】java-并发之锁对象
Lock Objects
Synchronized code relies on a simple kind of reentrant lock. This kind of lock is easy to use, but has many limitations. More sophisticated locking idioms are supported by the java.util.concurrent.locks package. We won't examine this package in detail, but instead will focus on its most basic interface, Lock.
Lock objects work very much like the implicit locks used by synchronized code. As with implicit locks, only one thread can own a Lock object at a time. Lock objects also support a wait/notify mechanism, through their associated Condition objects.
The biggest advantage of Lock objects over implicit locks is their ability to back out of an attempt to acquire a lock. The tryLock method backs out if the lock is not available immediately or before a timeout expires (if specified). ThelockInterruptibly method backs out if another thread sends an interrupt before the lock is acquired.
Let's use Lock objects to solve the deadlock problem we saw in Liveness. Alphonse and Gaston have trained themselves to notice when a friend is about to bow. We model this improvement by requiring that our Friend objects must acquire locks for both participants before proceeding with the bow. Here is the source code for the improved model, Safelock. To demonstrate the versatility of this idiom, we assume that Alphonse and Gaston are so infatuated with their newfound ability to bow safely that they can't stop bowing to each other:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random; public class Safelock {
static class Friend {
private final String name;
private final Lock lock = new ReentrantLock(); public Friend(String name) {
this.name = name;
} public String getName() {
return this.name;
} public boolean impendingBow(Friend bower) {
Boolean myLock = false;
Boolean yourLock = false;
try {
myLock = lock.tryLock();
yourLock = bower.lock.tryLock();
} finally {
if (! (myLock && yourLock)) {
if (myLock) {
lock.unlock();
}
if (yourLock) {
bower.lock.unlock();
}
}
}
return myLock && yourLock;
} public void bow(Friend bower) {
if (impendingBow(bower)) {
try {
System.out.format("%s: %s has"
+ " bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
} finally {
lock.unlock();
bower.lock.unlock();
}
} else {
System.out.format("%s: %s started"
+ " to bow to me, but saw that"
+ " I was already bowing to"
+ " him.%n",
this.name, bower.getName());
}
} public void bowBack(Friend bower) {
System.out.format("%s: %s has" +
" bowed back to me!%n",
this.name, bower.getName());
}
} static class BowLoop implements Runnable {
private Friend bower;
private Friend bowee; public BowLoop(Friend bower, Friend bowee) {
this.bower = bower;
this.bowee = bowee;
} public void run() {
Random random = new Random();
for (;;) {
try {
Thread.sleep(random.nextInt(10));
} catch (InterruptedException e) {}
bowee.bow(bower);
}
}
} public static void main(String[] args) {
final Friend alphonse =
new Friend("Alphonse");
final Friend gaston =
new Friend("Gaston");
new Thread(new BowLoop(alphonse, gaston)).start();
new Thread(new BowLoop(gaston, alphonse)).start();
}
}
译文:
锁对象
同步代码依赖于一种简单的重入锁。这种锁很容易使用,但是却有很多限制。java.util.concurrent.locks包中支持许多更复杂的锁的规则。我们不会详细的校验
这个包中的东西,而是把重点放在其最基本的接口,锁上。
锁对象的工作原理和通过同步方法严格实现的锁一样。同严格实现的锁一样,一个线程一次只能拥有一个锁对象。通过关联Condition对象,锁对象也支持wait/notify机制。
锁对象比严格的锁最大的优势是他们能够从获得一个锁返回。tryLock方法从一个没有立即使用的锁或者超过期望时间(如果)的锁。lockInterruptibly方法会使若果另一个线程向这个锁发送一个中断请求返回。
让我们用锁对象来解决在Liveness中出现的死锁问题。Alphone和Gaston被训练成为各自都能注意到一个朋友正在鞠躬。我们要求我们的朋友必须获得锁让后再继续鞠躬的这种改进模型。这里是这种模型的改进模型,safelock。为了证明这些规则的功能性,我们假设Alphonse和Gaston都非常痴迷于他们的新发现安全的鞠躬,他们不能互相阻止对方的鞠躬。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random; public class Safelock {
static class Friend {
private final String name;
private final Lock lock = new ReentrantLock(); public Friend(String name) {
this.name = name;
} public String getName() {
return this.name;
} public boolean impendingBow(Friend bower) {
Boolean myLock = false;
Boolean yourLock = false;
try {
myLock = lock.tryLock();
yourLock = bower.lock.tryLock();
} finally {
if (! (myLock && yourLock)) {
if (myLock) {
lock.unlock();
}
if (yourLock) {
bower.lock.unlock();
}
}
}
return myLock && yourLock;
} public void bow(Friend bower) {
if (impendingBow(bower)) {
try {
System.out.format("%s: %s has"
+ " bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
} finally {
lock.unlock();
bower.lock.unlock();
}
} else {
System.out.format("%s: %s started"
+ " to bow to me, but saw that"
+ " I was already bowing to"
+ " him.%n",
this.name, bower.getName());
}
} public void bowBack(Friend bower) {
System.out.format("%s: %s has" +
" bowed back to me!%n",
this.name, bower.getName());
}
} static class BowLoop implements Runnable {
private Friend bower;
private Friend bowee; public BowLoop(Friend bower, Friend bowee) {
this.bower = bower;
this.bowee = bowee;
} public void run() {
Random random = new Random();
for (;;) {
try {
Thread.sleep(random.nextInt(10));
} catch (InterruptedException e) {}
bowee.bow(bower);
}
}
} public static void main(String[] args) {
final Friend alphonse =
new Friend("Alphonse");
final Friend gaston =
new Friend("Gaston");
new Thread(new BowLoop(alphonse, gaston)).start();
new Thread(new BowLoop(gaston, alphonse)).start();
}
}
养养眼^_^

【翻译十八】java-并发之锁对象的更多相关文章
- JAVA之旅(十八)——基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用
JAVA之旅(十八)--基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用 JAVA把完事万物都定义为对象,而我们想使用数据 ...
- Java并发之锁升级:无锁->偏向锁->轻量级锁->重量级锁
Java并发之锁升级:无锁->偏向锁->轻量级锁->重量级锁 对象头markword 在lock_bits为01的大前提下,只有当是否偏向锁位值为1的时候,才表明当前对象处于偏向锁定 ...
- 【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成 ...
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...
- java并发之固定对象与实例
java并发之固定对象与实例 Immutable Objects An object is considered immutable if its state cannot change after ...
- 转 Java并发之锁的升级
说明:本文大部分内容来自<并发编程的艺术>,再加上自己网络整理和理解 以下内容来自<java并发编程的艺术>作者:方鹏飞 魏鹏 程晓明 在多线程并发编程中synchronize ...
- Java并发编程(十)-- Java中的锁
在学习或者使用Java的过程中进程会遇到各种各样的锁的概念:公平锁.非公平锁.自旋锁.可重入锁.偏向锁.轻量级锁.重量级锁.读写锁.互斥锁.死锁.活锁等,本文将简概的介绍一下各种锁. 公平锁和非公平锁 ...
- JAVA并发之锁获取步骤及锁优化
在另外的两篇文章中先后介绍了轻量级同步关键字volatile和重量级锁关键字synchronized,这两个关键字是Java语言中进行线程同步的基本方式(当然还有ReentrenLock等显式锁方式) ...
- 【翻译十五】-java并发之固定对象与实例
Immutable Objects An object is considered immutable if its state cannot change after it is construct ...
随机推荐
- 这些情况下onReume不应该是你的选择
面试Android程序员的时候问过以下几个基本问题,得到的回答经常不尽人意: 1, Activity A跳转到Activity B,Activity B完成后,Activity A要刷新一下自己的数据 ...
- ARPACK在window visual Studio的安装配置
ARPACK是一个求解大规模稠密/稀疏矩阵问题的库,最近在做特征值问题时用到.ARPACK这库相当古老,最早是RICE的一帮人弄的.LAPACK也差不多,貌似是美帝某个.gov发起的.这俩源代码是Fo ...
- php中array_filter的使用
这是今天在做作业的时候遇到的一个问题,不知道大家有没有遇到同样的问题,就是去除数组中不符合我们条件的数据并且保留其键名. 言归正传: array array_filter ( array $input ...
- shiro学习中报错解决方法
[1] 最近在学习shiro,在学习过程中出现了一个问题,报错如下: org.apache.shiro.UnavailableSecurityManagerException: No Security ...
- [转载]能不能同时用static和const修饰类的成员函数?
题目(一):我们可以用static修饰一个类的成员函数,也可以用const修饰类的成员函数(写在函数的最后表示不能修改成员变量,不是指写在前面表示返回值为常量).请问:能不能同时用static和con ...
- 【leetcode】Word Ladder
Word Ladder Total Accepted: 24823 Total Submissions: 135014My Submissions Given two words (start and ...
- 【leetcode】Unique Paths II
Unique Paths II Total Accepted: 22828 Total Submissions: 81414My Submissions Follow up for "Uni ...
- ffmpeg-20160525-git-bin
ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...
- Effective C++ -----条款27:尽量少做转型动作
如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts.如果有个设计需要转型动作,试着发展无需转型的替代设计. 如果转型是必要的,试着将它隐藏于某个函数背后.客户随后可以调用该 ...
- 简述memcached中的一致哈希
memcached是一个开源的高性能分布式内存对象缓存系统. 其实思想还是比较简单的,实现包括server端(memcached开源项目一般只单指server端)和client端两部分: server ...