Java中常见的锁

简介

悲观锁和乐观锁

悲观锁

悲观锁是一种悲观思想,它认为数据很可能被其他线程修改,所以悲观锁在持有数据的时候总会把"资源"或者"数据"锁住,这样其他线程想请求这个资源的时候就会阻塞,直到悲观锁把资源释放为止。

体现

1.传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁,悲观锁的实现往往依靠数据库本身的锁功能实现。
2.Java 中的 Synchronized 和 ReentrantLock 等独占锁(排他锁)也是一种悲观锁思想的实现。

乐观锁

乐观锁的思想与悲观锁的思想相反,它总认为资源和数据不会被别人所修改,所以读取不会上锁,但是在进行写入操作的时候会判断当前数据是否被修改过。如果该数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新,则根据不同的实现方式执行不同的操作,如报错或者自动重试。

体现

1.版本号机制是在数据表中加上一个 version 字段来实现,表示数据被修改的次数,当执行写操作并且写入成功后,version = version + 1,当线程A要更新数据时,在读取数据的同时也会读取 version 值,在提交更新时,若刚才读取到的 version 值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。
2.在Java中,过使用无锁编程来实现,最常采用的是CAS算法;java.util.concurrent.atomic包下面的原子类递增操作就是使用 CAS(Compare-and-Swap,即比较并替换)自旋实现的。

悲观锁适合写操作多的场景,先加锁可以保证写操作时数据正确。
乐观锁适合读操作多的场景,不加锁的特点能够使其读操作的性能大幅提升。

你可能感兴趣的:(Java中常见的锁)