1. 乐观锁【CAS】:到我就用,不行就等,读操作无所谓

  2. 悲观锁【synchronized,vector,hashtable】:读写都上锁

  3. 自旋锁【CAS】:锁的线程循环查询,知道获得使用权,只要循环的时间不长,就可以忍受。默认10次,-XX:PreBlockSpin来修改

  4. 可重入锁(递归锁)【synchronized,Reentrantlock,Lock】:这是一种技术。线程可重复获取一把锁,并且每次都会将计数加一,同样的,释放锁也需要将计数归零才行。,

    • 作用是避免死锁。首先可重入代表的是同一个线程可能代表着不同的类,但是还是可以进入并获取锁。

      • 而递归锁则表示的是我们所说的不同的类即当前类的父类或子类。一个线程可能会试图调用自己的父类获取对应的方法,当方法对应的是非重入锁,那么当前的子类需要先释放锁,在对父类的方法加锁,但此时我两个都要,自然就麻烦了,锁死了。
      • 而使用冲入锁,我们处于同一个线程,即使要面对的是两个加锁的方法,系统会检测到这是同一个线程,就会只将对应的锁计数加一,表明该线程同时控制着两个带锁的方法。
  5. 读写锁【ReentrantReadWriteLock,CopyOnWriteArrayList、CopyOnWriteArraySet】:这是一种技术。顾名思义就是有读锁和写锁,读锁和写锁是互斥的。获取读锁的时候,写锁就不能操作,而且读锁可以有多个线程共同读取内容。

  6. 公平锁【Reentrantlock(true)】:这是一种思想。主要是在多线程环境中,多个线程同时申请则放在队列中排队领取。好处是线程总有希望获得锁,不至于饿死

  7. 非公平锁【synchronized,Reentrantlock(false)】:一样是一种思想。线程进来之后先争抢锁,抢不到就放到队列中排队。好处是争抢后线程直接就能获得锁进行工作,省了一点CPU的唤醒线程的工作量。坏处是可能有线程排队排到死。

  8. 共享锁【ReentrantReadWriteLcok的读锁】:又是一种思想。顾名思义,就是多个线程能够使用同一个线程,虽然独立写一个定义,但基本等同于前面读写锁中的读锁。需要注意的是由于其中的写锁是独占锁,因此写操作必须等待读锁全部释放,避免读取的数据被污染。

  9. 独占锁【synchronized、vector、hashtable、ReentrantReadWriteLock的写锁】:思想。基本等同于悲观锁和互斥锁。大概率就是指写锁。

  10. 重量级锁【synchronized】:一种称谓。synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的,监视器锁本身依赖底层的操作系统的 Mutex Lock来实现。由于使用Mutex Lock需要将当前线程挂起并从用户态切换到内核态来执行,成本非常高。

  11. 轻量级锁:JDK6之后引入。当环境没什么竞争,就是用轻量级锁,使用CAS操作。但是当进入多线程环境,轻量级锁就会膨胀为重量级锁。【但此时还不是简单的重量级锁,还额外有CAS操作】

  12. 偏向锁:JDK6引入。java的对象头中对应的位置可用于保存自己被哪个线程把持了锁。

    若使用了偏向锁,当一个线程试图使用该对象时,对象首先检查上一次是否也是被这个线程使用,如果是的,就没必要做额外的工作,否则更新自己对象头中的对应的线程为当前线程【这一过程使用了CAS操作进行更新】。

    虽然,环境中可能有多个线程,只要对象不被多个线程竞争,偏向锁就可行且轻量。

  13. 分段锁:一种机制。就是将对象划分为多个部分,这样就可以多个线程同时对该对象进行操作,ConcurrentHashMap在JDK1.7及之前都是在内部使用分段锁实现的。

  14. 互斥锁:不管做什么,都只能一个线程进入操作。

  15. 同步锁:等同于互斥锁。

  16. 锁粗化:一种优化技术。主要是如果加锁和解锁的操作处于一个对象中,或处于其它一种整体内部,为了减少锁的操作,就把锁的范围扩大为对应的整体。

  17. 锁消除:优化技术。如果JVM发现某些共享变量不会被线程竞争,就消除对应的锁。【判断的依据是逃逸分析技术,如果对象不发生逃逸,则认为是线程私有的,就不需要加锁】

  18. Lock:java中锁的接口。必须使用unLock()方法才能释放锁,如果发生异常,就容易造成死锁。【而synchronized在发生异常后,会自动释放锁】