是否有另一种使用CAS操作在Java中编写同步块的方法?

时间:2015-01-18 19:43:47

标签: java multithreading concurrency java.util.concurrent

我有两个同步的块,它们将被两个并发线程大量访问。我想减少争用和上下文切换。有没有办法在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类,因为我觉得它不会有所作为。我想使用CAS。

2 个答案:

答案 0 :(得分:6)

您可以通过以下方式替换同步块:

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,所以再一次测试很重要。

答案 1 :(得分:2)

根据实际情况,使用CAS的自旋锁可能会也可能不会提高性能。如果块中的代码有点长且耗时,则同步仍然是您最安全的选择。

您是否可以尝试使数据不可变,以便不同的线程使用不同的数据副本而不需要锁定?