先看名字,乐观锁和悲观锁,乐观的人会假设每一次的操作都是线程安全的,只有最后返回数据的时候才校验一下。悲观的人觉得每一次的操作都是不安全的,一次只能一个人进行操作。
有这样一个方法
public class Sequence(){
private int value;
public synchronized int next(){
return value++;
}
}
如果现在有100个线程要执行这个方法,但是由于关键字sunchronized的存在,大家必须获得那把唯一的锁才能进入方法,当某个线程获得了锁之后,其他的99个线程只能进入锁池等待线程执行完释放锁之后继续争抢。
这就是悲观锁,也叫互斥锁,就是同一时刻只有获得锁的线程才有资格去操作共享资源,其他线程都被阻塞了,被放到一个锁池的地方等待。
乐观锁的意思就是不管几个线程要执行这个方法,大家都可以执行,但是返回的时候需要比较一下自己拿到的数据和一开始是否一致,如果一致说明没有人动过数据,那可以放心的返回。如果数据发生变化,说明自己在执行这个方法的时候时间片到了,但其他线程这时候已经进来执行完了,此时只能返回一开始重新执行,下面看一个方法
public int next(){
while(true){
int A=读取的值,也就是公用资源;
int B=A+1;
if(A==公用资源的值){
return B;
}
}
}
在这里是一个死循环,只有真正做到线程安全的时候才会停止。
总结:乐观锁根本不会加锁,每个线程都可以进入这个方法,读取数据来操作,最后使用CAS来判读本次操作是否有效,如果存在CAS里的值被修改过,那就再次循环尝试。