java锁
一、乐观锁
乐观锁是一种乐观思想,即认为读多写少,每次拿数据时候都认为别人不会修改,所以不会上锁,但是在更新数据时候会判断在此期间是否有人更新过。java 中的乐观锁基本都是通过 CAS 操作实现的,CAS 是一种更新的原子操作,比较当前值跟传入 值是否一样,一样则更新,否则失败。
二、悲观锁
悲观锁是就是悲观思想,即认为写多,每次拿数据都以为别人会修改,所以每次拿数据时都会上锁。如:Synchronized就是典型的悲观锁。
三、可重入锁(也称递归锁)
指的是同一线程外层函数获得锁之后,内层递归函数任然能获取该锁的代码。在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。
坦白说:线程可以进入任何一个它已经拥有的锁所同步着的代码块。如下代码:
method1()可拥有method2()的锁,不需要竞争抢锁。可重入锁的最大作用是避免死锁。ReentrantLock/Synchronized就是典型的可重入锁。
四、自旋锁(spinlock)
是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式区尝试获取锁,这样的好处是减少线程上下问你切换的消耗,缺点是循环会消耗CPU。
五、独占锁(写锁)/共享锁(读锁)/互斥锁
独占锁:指该锁一次只能被一个线程所持有,对ReenTranLock和synchronized而言都是独占锁。
共享锁:指该锁可被多个线程所持有。
对ReentrantReadWriteLock其读锁就是共享锁,其写锁就是独占锁。读锁的共享锁可保证并发读是非常高效的,读写、写读、写写的过程是互斥的,读写分离。
六、公平锁与非公平锁
公平锁:是指多线程按照申请锁的顺序来获取锁。
非公平锁:是指多个线程获取锁的顺序并不是按照申请锁的顺序,上来就直接尝试占有锁,如果尝试失败,就采用类似公平锁的方式。有可能后申请的线程比先申请的线程优先获取锁。在高并发下,有可能会造成优先级反转或饥饿现象。
并发包中ReentrantLock的创建可以指定构造函数的boolean类型来得到公平锁或非公平锁,默认是非公平锁。
非公平锁的优点是在于吞吐量比公平锁大。Synchronized也是一种非公平锁。