大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
本篇文章为大家展示了如何理解java中锁与并发,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
创新互联公司服务项目包括娄底网站建设、娄底网站制作、娄底网页制作以及娄底网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,娄底网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到娄底省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
在java虚拟机的实现中,每个对象都有一个对象头,用于保存对象的系统信息。对象头中有一个称为Mark Word
的部分,它是实现锁的关键。在32位系统中,Mark Word
为一个32位的数据,在64位系统中,它占64位。它是一个多功能的数据区,可以存放对象的哈希值、对象年龄、锁的指针等信息。一个对象是否占用锁、占用哪个锁,就记录在这个Mark Word
中。
以32位系统为例,普通对象的对象头如下:
hash: 25 --------->| age: 4 biased_lock: 1 lock: 2
它表示Mark Word
中有25位表示对象的哈希值,4位表示对象的年龄,1位表示是否为偏向锁,2位表示锁的信息。
偏向锁是jdk 1.6提出的一种锁优化方式。其核心思想是,如果程序没有竞争,则取消之前已经取得锁的线程同步操作。也就是说,某一锁被线程获取后,就会进入俯身模式,当线程再次请求这个锁时,无须再进行相关的同步操作,从而节省了操作时间。如果在此期间有其他线程进行了锁请求,则锁退出偏向模式。在jvm中,使用-XX:+UseBiasedLocking
可以设置启用偏向锁。
对于偏向锁的对象,它的格式如下:
[JavaThread* | epoch | age | 1 | 01]
前23位表示持有偏向锁的线程,后续2位表示偏向锁的时间戳(epoch
),4位表示对象年龄,年龄后固定为1,表示偏向锁,最近2位为01,表示可偏向/未锁定。
偏向锁示例:
package jvm.chapter08; import java.util.List; import java.util.Vector; /** * 使用一个线程对Vector进行写入操作,由于对Vector的访问内部都用同步锁控制, * 每次add()操作都会请求numberList对象的锁。 * * @author chengyan * @date 2019-11-17 7:41 下午 */ public class Demo01 { public static ListnumberList = new Vector (); public static void main(String[] args) throws InterruptedException { long begin = System.currentTimeMillis(); int count = 0; int startnum = 0; while(count < 1000_0000) { numberList.add(startnum); startnum += 2; count++; } long end = System.currentTimeMillis(); System.out.println(end - begin); } }
使用参数-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0 -client -Xmx512m -Xms512m
运行,结果如下:
227
这说明程序用227毫秒完成所有的工作。参数-XX:BiasedLockingStartupDelay
表示虚拟机在启动后立即使用偏向锁。如不设置该参数,虚拟机默认会在启动后4秒后,才启用偏向锁,考虑到程序运行时间较短,故做此设置,尽早启用偏向锁。
若禁用偏向锁,则只需使用如下参数启动程序:
-XX:-UseBiasedLocking -client -Xmx512m -Xms512m
结果如下:
363
当对象处于轻量级锁时,其中Mark Word
如下(00表示最后2位的值):
[ptr | 00] locked
此时,它指向存放在获得锁的线程栈中的该对象的真实对象头。
当对象处于轻量级锁时,其中Mark Word
如下:
[ptr | 10] monitor
此时,最后2位为10,整个 Mark Word
指向 Minitor
的指针。
当对象处理于普通的未锁定状态时,其格式如下:
[header | 0 | 01|] unlocked
前29位表示对象的哈希值、年龄等信息。倒数第3位为0,最后两位为01,表示未锁定。可以发现,最后两位的值和偏向状态是一样的,此时虚拟机通过倒数第3位来区分是否为偏向锁。
上述内容就是如何理解java中锁与并发,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联行业资讯频道。