博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并发编程实战4-自旋锁,死锁,以及锁重入详解
阅读量:4126 次
发布时间:2019-05-25

本文共 3270 字,大约阅读时间需要 10 分钟。

  • 锁重入:也叫做递归锁
    • 某个线程获得一个已经由它自己持有的锁对象,那么这个请求就会成功,即重入
    • 重入是对本线程来说,即本线程多资源可以多次加锁进入,而不会出现阻塞
    • 在JAVA环境下 ReentrantLock 和synchronized 都是可重入锁
    • 场景:比如数据库中,用户名和密码保存在本地txt文件中,则登录验证方法和更新密码方法都应该被加synchronized,那么当更新密码的时候需要验证密码的合法性,所以需要调用验证方法,相当于二次入锁,此时是可以调用的。
  • 自旋锁
    • 当一个线程访问的资源被其他线程占用时,此线程并不会等待,而是一直尝试获取锁,即仍然占用CPU,直到获取锁为止。
  • 死锁
    • 资源互斥导致互相占用不放

  • volatile变量原理与使用
    • Volatile称之为轻量级锁,被volatile修饰的变量,在线程之间是可见的(处理器内部lock指令标记)。
    • 可见:一个线程修改了这个变量的值,在另外一个线程中能够立即读到这个修改后的值。
    • volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。Volatile 变量具有synchronized 的可见性特性,但是不具备原子特性。
    • 要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:
      • 对变量的写操作不依赖于当前值。
      • 该变量没有包含在具有其他变量的不变式中。
        第一个条件的限制使 volatile 变量不能用作线程安全计数器。虽然增量操作(x++)看上去类似一个单独操作,实际上它是一个由读取-修改-写入操作序列组成的组合操作,必须以原子方式执行,而 volatile 不能提供必须的原子特性。实现正确的操作需要使 x 的值在操作期间保持不变,而 volatile 变量无法实现这点。(然而,如果将值调整为只从单个线程写入,那么可以忽略第一个条件。)

  • JDK1.5提供的原子类原理与应用

    Atomic一词跟原子有点关系,后者曾被人认为是最小物质的单位。计算机中的Atomic是指不能分割成若干部分的意思。如果一段代码被认为是Atomic,则表示这段代码在执行过程中,是不能被中断的。通常来说,原子指令由硬件提供,供软件来实现原子方法(某个线程进入该方法后,就不会被中断,直到其执行完成)
    在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀”LOCK”,经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。

    • 原子变量的原子操作也是用到了锁,只不过这个是硬件指令级别的锁,比我们软件实现的锁高效很多,更重要的是如果出现了冲突,只是不停的循环重试,而不会切换线程。如:do{ }while 循环调用一个本地方法。
  • Lock锁的认识与使用

    • lock的使用类似如下:
      lock使用
    • 使用方式类似于synchronized,具有相同的互斥性和内存可见性,但是更加灵活,加锁和放锁可以由使用者自己确定
    • 优势:
      • synchronized锁可能出现异常而导致中断,无法释放锁,但是通过使用lock,可以直接将lock放在异常finally中,强制释放锁。
      • 可以方便的实行公平性
  • AbstractQueuedSynchronizer(AQS)详解

    • AQS是一个用来构建锁和同步器的框架,它在内部定义了一个int state变量,用来表示同步状态.在LOCK包中的相关锁(常用的有ReentrantLock、 ReadWriteLock)都是基于AQS来构建.然而这些锁都没有直接来继承AQS,而是定义了一个Sync类去继承AQS.那么为什么要这样呢?because:锁面向的是使用用户,而同步器面向的则是线程控制,那么在锁的实现中聚合同步器而不是直接继承AQS就可以很好的隔离二者所关注的事情。
    • 即AQS用来记录线程状态,并不管理线程,所以是内部定义,而不是直接继承
    • java.util.concurrent中的同步器类:

      • RentrantLock

        /** 源码         * Performs non-fair tryLock.  tryAcquire is implemented in         * subclasses, but both need nonfair try for trylock method.         */        final boolean nonfairTryAcquire(int acquires) {            final Thread current = Thread.currentThread();            int c = getState();            if (c == 0) {                if (compareAndSetState(0, acquires)) {                    setExclusiveOwnerThread(current);                    return true;                }            }            else if (current == getExclusiveOwnerThread()) {                int nextc = c + acquires;                if (nextc < 0) // overflow                    throw new Error("Maximum lock count exceeded");                setState(nextc);                return true;            }            return false;        }        protected final boolean tryRelease(int releases) {            int c = getState() - releases;            if (Thread.currentThread() != getExclusiveOwnerThread())                throw new IllegalMonitorStateException();            boolean free = false;            if (c == 0) {                free = true;                setExclusiveOwnerThread(null);            }            setState(c);            return free;        }
      • ReentrantReadWriteLock

  • 公平锁和非公平锁(是否考虑队列问题)

    • 公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得
    • 非公平锁(Nonfair):加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待
      非公平锁性能比公平锁高5~10倍,因为公平锁需要在多核的情况下维护一个队列,Java中的ReentrantLock 默认的lock()方法采用的是非公平锁。

转载地址:http://whepi.baihongyu.com/

你可能感兴趣的文章
【Python】学习笔记——-7.5、实例属性和类属性
查看>>
git中文安装教程
查看>>
虚拟机 CentOS7/RedHat7/OracleLinux7 配置静态IP地址 Ping 物理机和互联网
查看>>
Jackson Tree Model Example
查看>>
常用js收集
查看>>
如何防止sql注入
查看>>
maven多工程构建与打包
查看>>
springmvc传值
查看>>
Java 集合学习一 HashSet
查看>>
在Eclipse中查看Android源码
查看>>
Android使用webservice客户端实例
查看>>
层在页面中的定位
查看>>
[转]C语言printf
查看>>
C 语言 学习---获取文本框内容及字符串拼接
查看>>
C 语言学习 --设置文本框内容及进制转换
查看>>
C 语言 学习---判断文本框取得的数是否是整数
查看>>
C 语言 学习---ComboBox相关、简单计算器
查看>>
C 语言 学习---ComboBox相关、简易“假”管理系统
查看>>
C 语言 学习---回调、时间定时更新程序
查看>>
C 语言 学习---复选框及列表框的使用
查看>>