“锁”相关总结
侧边栏壁纸
  • 累计撰写 307 篇文章
  • 累计阅读 104.3万

“锁”相关总结

TOTC
2014-01-04 / 683 阅读 / 正在检测是否收录...

synchronized

1.JDK 6之后,synchronized目前锁一共有4种状态,级别从低到高依次是:无锁、偏向锁、轻量级锁和重量级锁。锁状态只能升级不能降级。

偏向锁,一段同步代码一直被一个线程所访问,那么该线程会自动获取锁,降低获取锁的代价。

轻量级锁,是指当锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。

重量级锁,若当前只有一个等待线程,则该线程通过自旋进行等待。但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁升级为重量级锁。

重量级锁,除了拥有锁的线程以外的线程都阻塞。

ReentrantLock

Synchronized,Java虚拟机完成,不公平锁,ReentrantLock和synchronized都是可重入锁。

ReentrantLock,类层面的实现,户自己去操作,可以指定锁是公平的还是非公平的。

NonReentrantLock,不可重入锁。

ReentrantLock更灵活,在Hashtable和ConcurrentHashMap中体现得淋漓尽致

synchronized的话,锁的范围是整个方法或synchronized块部分;而Lock因为是方法调用,可以跨方法,灵活性更大。

和synchronized相比,ReentrantLock提供给用户多种方法用于锁信息的获取,比如可以知道lock是否被当前线程获取、lock被同一个线程调用了几次、lock是否被任意线程获取等等。

ReentrantLock的某些方法可以决定多长时间内尝试获取锁,如果获取不到就抛异常,这样就可以一定程度上减轻死锁的可能性,如果锁被另一个线程占据了,synchronized只会一直等待,很容易错序死锁。

之后,synchronized做了诸多优化,效率上synchronized和ReentrantLock应该是差不多。

公平锁 VS 非公平锁

公平锁:线程直接进入队列中排队,等待队列中除第一个线程以外的所有线程都会阻塞,优点是等待锁的线程不会饿死,缺点是整体吞吐效率相对非公平锁要低。

非公平锁:如果此时锁刚好可用,线程有几率不阻塞直接获得锁,CPU不必唤醒所有线程,缺点是处于等待队列中的线程可能会饿死,或者等很久才会获得锁。

乐观锁 VS 悲观锁

自旋锁 VS 适应性自旋锁

自旋锁:自旋等待虽然避免了线程切换的开销,但它要占用处理器时间。如果锁被占用的时间很短,自旋等待的效果就会非常好。反之,如果锁被占用的时间很长,那么自旋的线程只会白浪费处理器资源。

适应性自旋锁:自适应意味着自旋的时间(次数)不再固定,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。

可重入锁 VS 非可重入锁

可重入锁,又名递归锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提锁对象得是同一个对象或者class),不会因为之前已经获取过还没释放而阻塞。

独享锁 VS 共享锁

ReentrantLock和ReentrantReadWriteLock

volatile

当写一个volatile变量时,JMM会把该线程对应的本地内存中的变量强制刷新到主内存中去,导致其他线程中的缓存无效。

volatile是一种轻量级的同步机制,一是保证共享变量对所有线程的可见性;二是禁止指令重排序优化。volatile对于单个的共享变量的读/写具有原子性,但是像num++这种复合操作,volatile无法保证其原子性。

可以用num.incrementAndGet()。

52

评论

博主关闭了所有页面的评论