CAS原理: if(预期原值==内存值) 内存值=新值; else 不操作
乐观锁是当前线程乐观的认为执行操作不会造成线程安全问题,
例如本例中的实现:
lock()中使用null去与 atomicObj包含的值比较,如果一致则把本身赋给atomicObj,否则循环执行此操作
如果没有其他线程干扰的情况下atomicObj包含的值为null,
lock()操作乐观的认为它的执行不会与其他线程冲突,或者受到冲突后少量自旋可解决冲突
乐观锁是当前线程乐观的认为执行操作不会造成线程安全问题,
例如本例中的实现:
lock()中使用null去与 atomicObj包含的值比较,如果一致则把本身赋给atomicObj,否则循环执行此操作
如果没有其他线程干扰的情况下atomicObj包含的值为null,
lock()操作乐观的认为它的执行不会与其他线程冲突,或者受到冲突后少量自旋可解决冲突
从上面也能看出,乐观所适用于竞争不太激烈的场景,使用它不会导致线程阻塞,省去了切换线程状态产生的性能消耗,我们可以通过细化锁粒度的调优方式降低竞争
public class SpinLock {
private AtomicReference<SpinLock> atomicObj = new AtomicReference<SpinLock>();
public void lock() {
// CAS操作:
// 内存值=atomicObj包含的SpinLock对象
// 预期原值=null
// 新值=this
// 如果CAS操作不成功,则自旋
while (!atomicObj.compareAndSet(null, this)) {
}
}
public void unlock() {
atomicObj.set(null);
}
public static void main(String[] args) {
class Task implements Runnable{
private SpinLock spinLock = new SpinLock();
private long count = 0;
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
try {
spinLock.lock();
count += 1;
count += 1;
} finally {
spinLock.unlock();
}
}
}
public long getValue(){
return count;
}
}
// 线程数量
final int THREAD_NUM = 100;
Task task = new Task();
try {
for (int i = 0; i < THREAD_NUM; i++) {
Thread t = new Thread(task);
t.start();
t.join();
}
System.out.println("结果:" + task.getValue());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}