jdk1.6中为了减少获取锁和得到锁带来的性能消耗,引入了偏向锁和轻量级锁。再java1.6中,锁有四种状态。
其实锁是不存在多线程竞争的,且总是由同一线程多次获得,为了让线程获得锁的代价更低。引入了偏向锁。当一个线程访问同步代码块并获取锁时,会在对象头和栈帧中锁记录中记录偏向锁的线程id。 当以后该线程再进入同步代码块的时候,只需要简单的测试对象头里面的Mark Word的存储结构是否存储着指向当前线程的偏向锁。如果,测试成功,那么久表示获得了锁。如果测试失败,那么就需要测试一下偏向锁的标识是否设置了1,如果是1则尝试使用CAS将对象头的偏向锁指向当前线程,如果不是1则使用CAS竞争锁。
偏向锁使用了竞争出现才释放锁的机制,当其他线程尝试晶振偏向锁时持有偏向锁的线程菜会释放锁。而且需要等待全局安全点。安全点指的是,在这个时间点上没有正在执行的字节码。撤销的时候先检查持有偏向锁的线程是否还活着,如果线程不处于活动状态,则将对象头设置为成无锁状态。如果线程仍然活着,拥有偏向锁的栈会被执行,遍历偏向对象的锁记录,栈中的锁记录和对象头的Mark Word要么重新偏向其他线程,要么恢复到无所或标记对象不适合作为偏向锁,最后唤醒。
轻量级锁
加锁:
线程在执行同步块之前,JVM会先在当前线程的栈桢中创建用于存储锁记录的空间,并将对象头中的Mark Word复制到锁记录中,官方称为Displaced Mark Word。然后线程尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。
解锁:
轻量级解锁时,会使用原子的CAS操作将Displaced Mark Word替换回到对象头,如果成
功,则表示没有竞争发生。如果失败,表示当前锁存在竞争,锁就会膨胀成重量级锁。图2-2是
两个线程同时争夺锁,导致锁膨胀的流程图。
偏向锁:加锁和解锁不需要额外的消耗,但是线程之间存在锁竞争,锁撤销的时候消耗要大。
轻量级锁:竞争的线程不会阻塞,提高了线程的响应速度。如果始终得不到锁,那么就会自旋消耗cpu。 目的是为了追求相应时间。
重量级锁:不会使用自旋,不消耗cpu。线程阻塞,响应慢,但是追求吞吐量。
参考java编程之美 ,记录本文是为了加深自己对并发的锁的印象
matlab/simulink电力电子仿真单相变压器的设置 感觉网上的教程要么是英文的要么...
Frida框架逆向入门-第一篇 1、安装Frida 2、下载安装Frida-server 3、使用frida ...
本来这篇是要写Python的可视化的,但无意中发现了一道题目,发现通过这道题可以...
web采集程序?网页抓取程序?小倫程序?不管怎么叫,这种程序应用倒是蛮广的。本...
最近做项目时遇到一个问题,明明加了response.sendRedirect() ,系统也执行了,但是...
SMIL 向 web 增加了对定时和媒介同步的支持。 SMIL 向 web 增加了对定时和媒介同...
一、简介 这是一款基于 JS 实现的超轻量级桌面版聊天软件。主要适用于私有云项目...
该配置为霍尔电机的位置环模式 该配置基于6.5寸、DC36V、15 对极、功率 250W - 3...
比较简洁的代码一: $str = '';$isMatched = preg_match('/^0(13|14|15|17|18)[0...
定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个...