Java锁类型
悲观锁、乐观锁
悲观锁:每次进行操作时都默认数据会被更改,对数据进行上排他锁,除了当前操作,其他线程不可访问
乐观锁:一般通过其他数据是否有被更高来确定当前数据是否未被更改,比如版本号或者时间戳,通常依赖数据库进行判断处理
自旋锁;通过判断当前数据的内存位置的值和预期值进行比对,如果比对通过则修改当前数据的值。在多线程下,其他自旋锁并不会进入等待,而是直接失败进行下一次循环判断。但是如果长时间比对失败,可能会由于自旋锁尝试次数过多导致cpu负荷过大。ABA问题:当某一个数据有A到B,再由B到A。这个过程中虽然最终结果是一样的,但整个过程中数据是有进行改变的,所以为了保证数据的安全性,需要加一个版本号来控制cas自旋数据
独享锁:仅当前事务获取锁状态,其他事务不能对加锁的数据进行读取或者修改
共享锁:多个事务共同持有,但只允许读取
互斥锁:只能被一个线程持有,其他线程想要获取加锁的数据则需要进入锁池,等待唤醒
读写锁:读锁可以被多个线程持有,但写锁只能被一个线程获取。当写锁被获取时,写锁对应的加锁数据会被锁定,后续其他持有该数据读锁的线程会进入等待,但写锁的唤醒优先于读锁
可重入锁/不可重入锁:锁进行重复获取,但要先获取许可,每次数据使用完毕会减少一次锁的许可数量,访问完毕后释放许可。可分为独占和共享,即是否只让一个线程访问
公平锁:先进先出,先获取锁的线程先进行释放,后到的线程先判断队列是否有等待线程,如果有会进入队列等待状态。
非公平锁:线程进行抢占锁,如果抢占失败将进入队列头等待唤醒,唤醒后再次抢占非公平锁