乐观锁【CAS】:到我就用,不行就等,读操作无所谓
悲观锁【synchronized,vector,hashtable】:读写都上锁
自旋锁【CAS】:锁的线程循环查询,知道获得使用权,只要循环的时间不长,就可以忍受。默认10次,-XX:PreBlockSpin来修改
可重入锁(递归锁)【synchronized,Reentrantlock,Lock】:这是一种技术。线程可重复获取一把锁,并且每次都会将计数加一,同样的,释放锁也需要将计数归零才行。,
作用是避免死锁。首先可重入代表的是同一个线程可能代表着不同的类,但是还是可以进入并获取锁。
读写锁【ReentrantReadWriteLock,CopyOnWriteArrayList、CopyOnWriteArraySet】:这是一种技术。顾名思义就是有读锁和写锁,读锁和写锁是互斥的。获取读锁的时候,写锁就不能操作,而且读锁可以有多个线程共同读取内容。
公平锁【Reentrantlock(true)】:这是一种思想。主要是在多线程环境中,多个线程同时申请则放在队列中排队领取。好处是线程总有希望获得锁,不至于饿死。
非公平锁【synchronized,Reentrantlock(false)】:一样是一种思想。线程进来之后先争抢锁,抢不到就放到队列中排队。好处是争抢后线程直接就能获得锁进行工作,省了一点CPU的唤醒线程的工作量。坏处是可能有线程排队排到死。
共享锁【ReentrantReadWriteLcok的读锁】:又是一种思想。顾名思义,就是多个线程能够使用同一个线程,虽然独立写一个定义,但基本等同于前面读写锁中的读锁。需要注意的是由于其中的写锁是独占锁,因此写操作必须等待读锁全部释放,避免读取的数据被污染。
独占锁【synchronized、vector、hashtable、ReentrantReadWriteLock的写锁】:思想。基本等同于悲观锁和互斥锁。大概率就是指写锁。
重量级锁【synchronized】:一种称谓。synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的,监视器锁本身依赖底层的操作系统的 Mutex Lock来实现。由于使用Mutex Lock需要将当前线程挂起并从用户态切换到内核态来执行,成本非常高。
轻量级锁:JDK6之后引入。当环境没什么竞争,就是用轻量级锁,使用CAS操作。但是当进入多线程环境,轻量级锁就会膨胀为重量级锁。【但此时还不是简单的重量级锁,还额外有CAS操作】
偏向锁:JDK6引入。java的对象头中对应的位置可用于保存自己被哪个线程把持了锁。
若使用了偏向锁,当一个线程试图使用该对象时,对象首先检查上一次是否也是被这个线程使用,如果是的,就没必要做额外的工作,否则更新自己对象头中的对应的线程为当前线程【这一过程使用了CAS操作进行更新】。
虽然,环境中可能有多个线程,只要对象不被多个线程竞争,偏向锁就可行且轻量。
分段锁:一种机制。就是将对象划分为多个部分,这样就可以多个线程同时对该对象进行操作,ConcurrentHashMap在JDK1.7及之前都是在内部使用分段锁实现的。
互斥锁:不管做什么,都只能一个线程进入操作。
同步锁:等同于互斥锁。
锁粗化:一种优化技术。主要是如果加锁和解锁的操作处于一个对象中,或处于其它一种整体内部,为了减少锁的操作,就把锁的范围扩大为对应的整体。
锁消除:优化技术。如果JVM发现某些共享变量不会被线程竞争,就消除对应的锁。【判断的依据是逃逸分析技术,如果对象不发生逃逸,则认为是线程私有的,就不需要加锁】
Lock:java中锁的接口。必须使用unLock()方法才能释放锁,如果发生异常,就容易造成死锁。【而synchronized在发生异常后,会自动释放锁】
xxxxxxxxxxLock可以获悉是否获取锁,也可以中断等待锁的线程。但JVM很难判断对象的锁是具体哪一个。【ReentrantLock是Lock的一个实现】