学习笔记之悲观锁乐观锁

 悲观锁与乐观锁       

悲观锁和乐观锁是操作数据的一种思想,乐观锁如同名字一般采取比较乐观的态度,认为操作数据期间不会有别的使用者操作这条数据,而悲观锁认为采取比较悲观的方式,认为操作数据期间时刻会有别的使用者操作这条数据。

数据库中的悲观锁和乐观锁:

悲观锁:for update添加行级锁

乐观锁:添加version版本字段

java编程中的悲观锁和乐观锁:

悲观锁:利用synchronize关键字进行实现

乐观锁:利用CAS(compare and swap)算法来实现

synchronized关键字:

//1.抢指定对象的锁
synchronized(对象) {

}

//2.抢当前对象(this)的锁
synchronized void f() {

}

//3.抢“类”的锁
static synchronized void f() {

}

swp算法:

算法涉及到三个操作数:

  • 需要读写的内存位置V
  • 需要进行比较的预期值A
  • 需要写入的新值U

CAS算法解析:

CAS具体执行时,当且仅当预期值A符合内存地址V中存储的值时,就用新值U替换掉旧值,并写入到内存地址V中。否则不做更新。

    private volatile int value;
 
 
    public final int get() {
        return value;
    }
 
 
    public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }
 
 
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
/**this代表当前对象AutomicInteger,valueOffset代表value的内存地址,
expect代表cas前读取到的value值,update表示操作后的更新值。
通过compareAndSet方法进行底层的CAS原子操作,
如果:valueOffset地址的值跟expect的值相等,则说明未被更新,则返回true。
否则在死循环中重试直到成功。*/

MySQL锁机制

MySQL的锁机制最显著的特点是不同的存储引擎支持不同的锁机制。

比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);

BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁;

InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。 


表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。 
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。 
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般 


从上述特点可见,很难笼统地说哪种锁更好,只能就具体应用的特点来说哪种锁更合适!仅从锁的角度来说:

表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用;

而行级锁则更适合于有大量按索引条件并发更新少量不同数据,

同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。

你可能感兴趣的:(service)