本文共 1322 字,大约阅读时间需要 4 分钟。
所有的并发模式在解决线程安全问题时,采用的方案都是**序列化访问临界资源**。即在同一时刻,只能有一个 线程访问临界资源,也称作同步互斥访问。Java 中,提供了两种方式来实现同步互斥访问:synchronized和 Lock 同步器的本质就是加锁 加锁目的:序列化访问临界资源,即同一时刻只能有一个线程访问临界资源(同步互斥访问)不过有一点需要区别 的是:当多个线程执行一个方法时,该方法内部的局部变量并不是临界资源,因为这些局部变量是在每个线程的私有栈中 因此不具有共享性,不会导致线程安全问题。
synchronized是对象锁,使用的时候需要传一个对象当成形参。 1、同步实例方法,锁是当前实例对象 2、同步类方法,锁是当前类对象 3、同步代码块,锁是括号里面的对象使用方式的具体代码,就不记录了
synchronized关键字被编译成字节码后会被翻译成monitorenter 和 monitorexit 两条指令分别在同步块逻辑代码的起始位置与结束置。 在使用synchronized的同步方法或同步代码块中,会在方法开始的时候有一个monitorenter指令,在结束的时候有一个monitorexit指令。 具体Monitor代表什么我也不太清楚,就知道是每个对象都是一个Monitor,是用c++语言写的,这个没去研究了
无锁状态是使用了synchronized关键字的方法,在线程开始时没有用到或者锁已经消除。
当一个线程A首先获取到了锁,这个时候锁还没有消除,线程A再次去获取锁,发现此时的持有锁的是线程A,这个时候就让线程A再次获得锁并将锁升级为偏向锁。当这个线程再次请求锁时,无需再做任何同步操作,即获取锁的过程,这样就省去了大量有关锁申请的操作,从而也就提供程序的性能。 用处:当一个线程多次获取锁的时候可以减少线程开销。
如果线程A已经获得了锁,线程B获取锁,这时候B肯定会获取锁失败。如果线程A此时刚好要结束,则撤销偏向锁升级为轻量级锁。在轻量级锁结束前,线程B会进入自旋锁状态,一直去获取锁,就相当于轮询了一定次数还没有获取锁,就停止轮询。升级为重量级锁。 用处:轻量级锁能够提升程序性能的依据是“对绝大部分的锁,在整个同步周期内都不存在竞争”
升级成重量级锁之后,就等A线程释放锁,再唤醒B线程获取锁。
还有一个逃逸分析就不在这个里面记录了
我的理解是根据state这个状态值去获取锁,唤醒锁的操作等等等等等等。感觉有好多知识点~害,还没有总结好,现在只是看了几遍源码,还不能去熟练总结。
AQS很重要,因为阻塞队列用的也是加锁,然后阻塞队列会引入条件队列。后面的线程池、mq、dobbo等中间件都用到了阻塞队列。也是其它并发工具类的基础。
转载地址:http://aikgn.baihongyu.com/