zoukankan      html  css  js  c++  java
  • Java 锁(学习笔记)

    关于Java 锁的知识整理与回顾(个人笔记):

    锁有哪些,分别用来干嘛?

    Java实现锁有两种方式,synchronized关键字和Lock

    (1)Lock(可判断锁状态)

    Lock是基于JDK层面实现。Lock的实现主要有ReentrantLock、ReadLock和WriteLock(引出锁分类:)

    ①乐观锁/悲观锁:

    乐观锁认为读多写少,乐观的认为拿数据时,不会改数据,所以不会上锁,而在更新数据时才会判断有无数据更新。悲观锁悲观的认为,写多,拿数据时先设定数据被修改了,每次在读写数据时都会上锁。

    ②公平锁/非公平锁:

    ReentrantLock在构造函数中提供是否公平锁的初始化方式(默认是非公平锁,就是说可以变成公平锁。即他和synchronized不同之处之一):

    public ReentrantLock() {
    sync = new NonfairSync();
    }
    public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }

    非公平锁不按套路出牌,有可能造成“饥饿”现象,但是它的实际执行效率、吞吐量要高于公平锁。

    ③独享锁/共享锁

    独享锁是指该锁一次只能被一个线程所持有 (ReentrantLock、 Synchronized),共享锁反之(ReadWriteLock)。

    ④互斥锁/读写锁(ReadWriteLock)

    互斥锁/读写锁像是独享锁/共享锁的具体的实现。(从字面意思就解释很清楚了)

    ⑤可重入锁

    指同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁(ReentrantLock和Synchronized)。可重入锁可一定程度避免死锁。

    ⑥自旋锁

    自旋锁是指尝试获取锁的线程不会阻塞,而是采用循环的方式尝试获取锁。“采用循环的方式”说明要一直占用CPU资源,浪费啊。在判断持有锁的线程会在很短的时间释放锁,用它就划算了,不用上下文来回切换了。

    ⑦偏向锁/轻量级锁/重量级锁

    这是jdk1.6中对Synchronized锁做的优化,对象头在不同锁状态下的标志位存储。
    偏向锁:加锁/解锁开销少,适用于只有一个线程访问同步块场景;轻量级锁:竞争线程不会堵塞,追求响应速度时用它;重量级锁:线程竞争不使用自旋,不会消耗CPU,吞吐量大。(尽量先考虑使用轻量级锁)

    (2)synchronized(不可判断锁状态):

    synchronized基于JVM层面实现。synchronized可以把任意的非Null的对象当作琐,它是非公平锁(且无法变成公平锁)、独享的可重入的悲观锁。使用synchronized比较省事儿,但是它是一个重量级操作,需要调用操作系统相关接口,性能较低,锁开销可能较大。

    同时,synchronized它在不断的被优化,在JDK1.5之后synchronized引入了偏向锁,轻量级锁和重量级锁,java 6有适应自旋、锁粗化、偏向锁等,之后还设置一堆标记位,减少获得锁和释放锁带来的性能消耗,锁开销小了,效率高了。

  • 相关阅读:
    再次或多次格式化导致namenode的ClusterID和datanode的ClusterID之间不一致的问题解决办法
    Linux安装aria2
    POJ 3335 Rotating Scoreboard 半平面交
    hdu 1540 Tunnel Warfare 线段树 区间合并
    hdu 3397 Sequence operation 线段树 区间更新 区间合并
    hud 3308 LCIS 线段树 区间合并
    POJ 3667 Hotel 线段树 区间合并
    POJ 2528 Mayor's posters 贴海报 线段树 区间更新
    POJ 2299 Ultra-QuickSort 求逆序数 线段树或树状数组 离散化
    POJ 3468 A Simple Problem with Integers 线段树成段更新
  • 原文地址:https://www.cnblogs.com/1693977889zz/p/10800854.html
Copyright © 2011-2022 走看看