有没有其他方法可以使用 CAS 操作在 Java 中编写同步块?
Is there an alternative way to write a synchronized block in Java using CAS operations?
我有两个同步块,它们将被两个并发线程大量访问。我想减少争用和上下文切换。有没有一种方法可以在 AtomicBoolean
?
上使用 CAS (CompareAndSet) 操作来实现?
例如:
private final Object lock = new Object();
// Thread A executing this
public final void methodA() {
synchronized(lock) {
...
}
}
// Thread B executing this
public final void methodB() {
synchronized(lock) {
...
}
}
我不想使用 java.util.concurrent.locks.Lock
class,因为我认为这没什么区别。我想用CAS。
您可以将同步块替换为:
private final AtomicBoolean flag = new AtomicBoolean();
while (!flag.compareAndSet(false, true));
try {
//your code here
} finally {
flag.set(false);
}
您应该在您的争用场景下对两者进行测试,以确保它确实提高了性能。 CAS 在小到温和的争用下效果最好。
正如@yshavit 评论的那样,the JIT may already perform that sort of optimisation for you,因此再次强调测试很重要。
根据实际情况,使用 CAS 的自旋锁可能会也可能不会提高性能。如果代码块中的代码有点长和耗时,synchronized 仍然是您最安全的选择。
您能否尝试使数据不可变,以便不同的线程使用不同的数据副本并且不需要锁?
我有两个同步块,它们将被两个并发线程大量访问。我想减少争用和上下文切换。有没有一种方法可以在 AtomicBoolean
?
例如:
private final Object lock = new Object();
// Thread A executing this
public final void methodA() {
synchronized(lock) {
...
}
}
// Thread B executing this
public final void methodB() {
synchronized(lock) {
...
}
}
我不想使用 java.util.concurrent.locks.Lock
class,因为我认为这没什么区别。我想用CAS。
您可以将同步块替换为:
private final AtomicBoolean flag = new AtomicBoolean();
while (!flag.compareAndSet(false, true));
try {
//your code here
} finally {
flag.set(false);
}
您应该在您的争用场景下对两者进行测试,以确保它确实提高了性能。 CAS 在小到温和的争用下效果最好。
正如@yshavit 评论的那样,the JIT may already perform that sort of optimisation for you,因此再次强调测试很重要。
根据实际情况,使用 CAS 的自旋锁可能会也可能不会提高性能。如果代码块中的代码有点长和耗时,synchronized 仍然是您最安全的选择。
您能否尝试使数据不可变,以便不同的线程使用不同的数据副本并且不需要锁?