我正在编写Java代码,我需要在其中实现线程。我正在浏览Java8API,并逐渐了解了盖章锁的情况。有人能告诉我为什么在多线程中使用StampedLocks吗?
提前谢谢。
发布于 2014-09-29 13:20:45
StampedLock是使用ReadWriteLock (由ReentrantReadWriteLock实现)的替代方案。StampedLock和ReentrantReadWriteLock的主要区别是:
因此,如果您的场景中有争用(否则您也可以使用synchronized
或简单的Lock
)和更多的读取器而不是作者,那么使用StampedLock可以显著提高性能。
但是,在下结论之前,您应该根据特定的用例来衡量性能。
海因茨·卡布茨写过关于StampedLocks 在他的通讯里的文章,他还创作了关于性能的介绍。
发布于 2014-09-30 17:58:28
java.util.concurrent.locks.StampedLock的API文档说:
StampedLocks被设计为用于开发线程安全组件的内部实用程序.它们的使用依赖于它们所保护的数据、对象和方法的内部属性的知识。它们不是可重入的,因此锁定的主体不应该调用其他可能试图重新获取锁的未知方法(尽管您可以将邮票传递给其他可以使用或转换它的方法)。读取锁模式的使用依赖于相关的代码部分是无副作用的.未经验证的乐观读取部分不能调用不知道可以容忍潜在不一致的方法。邮票使用有限的表示,并且不是密码安全的(例如,有效的邮票可以猜测)。邮票价值可在(不早于)一年连续运行后循环使用。没有使用或验证时间超过此期限的邮票可能无法正确验证。StampedLocks是可序列化的,但总是反序列化为初始的未锁定状态,因此它们对远程锁定没有用处。
例如-
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
void move(double deltaX, double deltaY) { // an exclusively locked method
long stamp = sl.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlockWrite(stamp);
}
}
double distanceFromOrigin() { // A read-only method
long stamp = sl.tryOptimisticRead();
double currentX = x, currentY = y;
if (!sl.validate(stamp)) {
stamp = sl.readLock();
try {
currentX = x;
currentY = y;
} finally {
sl.unlockRead(stamp);
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
void moveIfAtOrigin(double newX, double newY) { // upgrade
// Could instead start with optimistic, not read mode
long stamp = sl.readLock();
try {
while (x == 0.0 && y == 0.0) {
long ws = sl.tryConvertToWriteLock(stamp);
if (ws != 0L) {
stamp = ws;
x = newX;
y = newY;
break;
}
else {
sl.unlockRead(stamp);
stamp = sl.writeLock();
}
}
} finally {
sl.unlock(stamp);
}
}
}
发布于 2019-04-19 14:00:53
除了@assylias 回答
StampedLock支持使用方法tryConvertToWriteLock(long)
将readLock升级到writeLock
该类还支持有条件地提供跨三种模式的转换的方法。例如,方法tryConvertToWriteLock(long)试图“升级”一个模式,如果(1)已经在读模式中处于写入模式(2),并且没有其他读取器,或者(3)处于乐观模式,并且锁可用,则返回有效的写入标记。这些方法的形式是为了帮助减少在基于重试的设计中出现的一些代码膨胀。
代码样本:
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
// an exclusively locked method
void move(double deltaX, double deltaY) {
long stamp = sl.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlockWrite(stamp);
}
}
// a read-only method
// upgrade from optimistic read to read lock
double distanceFromOrigin() {
long stamp = sl.tryOptimisticRead();
try {
retryHoldingLock: for (;; stamp = sl.readLock()) {
if (stamp == 0L)
continue retryHoldingLock;
// possibly racy reads
double currentX = x;
double currentY = y;
if (!sl.validate(stamp))
continue retryHoldingLock;
return Math.hypot(currentX, currentY);
}
} finally {
if (StampedLock.isReadLockStamp(stamp))
sl.unlockRead(stamp);
}
}
// upgrade from optimistic read to write lock
void moveIfAtOrigin(double newX, double newY) {
long stamp = sl.tryOptimisticRead();
try {
retryHoldingLock: for (;; stamp = sl.writeLock()) {
if (stamp == 0L)
continue retryHoldingLock;
// possibly racy reads
double currentX = x;
double currentY = y;
if (!sl.validate(stamp))
continue retryHoldingLock;
if (currentX != 0.0 || currentY != 0.0)
break;
stamp = sl.tryConvertToWriteLock(stamp);
if (stamp == 0L)
continue retryHoldingLock;
// exclusive access
x = newX;
y = newY;
return;
}
} finally {
if (StampedLock.isWriteLockStamp(stamp))
sl.unlockWrite(stamp);
}
}
// Upgrade read lock to write lock
void moveIfAtOrigin(double newX, double newY) {
long stamp = sl.readLock();
try {
while (x == 0.0 && y == 0.0) {
long ws = sl.tryConvertToWriteLock(stamp);
if (ws != 0L) {
stamp = ws;
x = newX;
y = newY;
break;
}
else {
sl.unlockRead(stamp);
stamp = sl.writeLock();
}
}
} finally {
sl.unlock(stamp);
}
}
}
https://stackoverflow.com/questions/26094200
复制相似问题