类型 | synchronize | lock |
---|---|---|
存在层次 | JAVA关键字,在jvm层面 | 一个类 |
锁的释放 | 1.拿到锁的线程执行完,释放锁2.执行异常,jvm让线程释放 | 1.unlock 2.可中断.lockInterruptibly()获取锁,然后线程调用thread.interrupt()可释放锁; |
锁状态 | 无法判断 | 可以获取到锁的状态 |
锁类型 | 可重入 不可中断 非公平 | 可重入 可中断 可公平 |
性能 | 少量同步,锁竞争较少的情况时使用 | 大量的竞争时使用,读写分离可使用readwritelock |
简单讲讲锁的类别:
1.重入锁与不可重入锁的区别
重入锁就像这样
锁B先锁住对象。锁A仍然可以继续上锁,就想套娃一样把对象套在最中间。只需要一层一层打开就能获取到对象了。
不可重入锁 就像是一扇防盗门,锁能只有一个,要想上新的锁只能把旧的拆了。
2.公平锁和非公平锁
在于锁释放后,公平锁会根据线程申请的时间排序来分配锁,非公平锁则是所有线程都可以来争取锁
3.独享锁和共享锁
synchronize和ReentrantLock都是独享锁,读写锁中的读锁是共享锁,写锁是独享锁。
4.乐观锁/悲观锁
悲观锁就是synchronize和lock的使用认为大概率会有竞争的情况;
乐观锁就是不使用锁,常常采用的是CAS(compare and swap)算法,典型的例子就是原子类,通过CAS自旋实现原子操作的更新
5.分段锁
ConcurrentHashMap的锁段就是分段锁的使用,其实就是把锁细颗粒化
6.偏向锁/轻量级锁/重量级锁
待整理,java的锁升级
7.自旋锁
短时间未获取到锁的情况,线程并不会立马堵塞而是会循环尝试获取锁