最新要闻
- 环球观速讯丨《生化危机4:重制版》DLC正在开发中 艾达王是你的了
- 每日快播:深圳暴雨致航班取消 旅客情绪崩溃 跪求起飞 机场回应
- 环球通讯!全明星的三大遗憾,成就了这场本土篮球盛宴的缺憾之美
- 实时焦点:RTX 4070定了!还是你们讨厌的192位显存
- 每日看点!彻底没救了!《Forspoken》发售2个月后:RTX 4090依旧无法60帧
- 【播资讯】100亿捐款建大学 曹德旺:对标美国斯坦福 每个学生补贴5万
- 每日信息:做出莫斯利安的光明乳业:掉队了
- 女员工请假做试管婴儿被拒遭辞退 法院判了:恢复合同
- 热消息:4月10日上市 福特F-150猛禽烈焰风暴特别版官图发布 为中国市场而
- 能抄底了?一汽奥迪补贴经销商清库存 明星车型降价近10万
- 每日看点!马云回国首谈ChatGPT:机器只有“芯”而人有“心”
- 国产车赢麻了!报告:中国品牌占俄罗斯新车销量近40%
- 焦点信息:“高端家用车”?比亚迪汉DM-i试驾 极致的油耗和空间
- 天天视讯!国产两轮电动车龙头!雅迪2022年营收310亿创纪录:电动自行车销量大增
- 速读:前备箱门锁失灵?特斯拉扩大召回进口Model S
- 京东方iPhone 15灵动岛屏被曝漏光 苹果搬来三星救火:提前生产
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
Synchronized详解
sychronized是java多线程非常关键的一个知识点,这篇博客将从synchronized几个用法以及代码来学习。sychronized的作用是能够保证同一时间只有一个线程来运行这块代码,达到并发效果,如果没有保证并发的话,在多线程编码中就会产生致命问题,比如经典的i++,这也是数据库并发中经典的案例,i++并不是原子操作,分为三步,取数,操作,写数,参考这段代码,可以运行一下看下结果
public class showUnsafe1 implements Runnable{ static int i=0; @Override public void run() { for(int j=0;j<10000;j++){ i++; } } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new showUnsafe1()); Thread thread2 = new Thread(new showUnsafe1()); thread1.start(); // 启动thread1,在合适的时刻运行 thread2.start(); // 启动thread2,在合适的时刻运行 thread1.join(); // 让主线程等待thread1运行完 thread2.join(); // 让主线程等待thread2运行完 System.out.println(i); }}
一、synchronized四种用法
synchronized为啥这么神奇,无它,加锁而已,不少八股文喜欢分为两种锁,一种是对象锁,一种是类锁,还可以分为方法锁,代码块锁,静态锁,class锁,我们通过代码学习他们如何使用
(资料图)
1.对象锁:方法锁
方法锁是用synchronized修饰的一个类方法,作用方法即是方法作用域,除了这个方法要同步,其余不需要
public class SynchronizedObjectMethod implements Runnable{ private static SynchronizedObjectMethod instance=new SynchronizedObjectMethod(); public synchronized void method(){ System.out.println("我是对象锁的方法修饰符形式。我叫"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"运行结束"); } @Override public void run() { method(); } public static void main(String[] args) { Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); while(thread1.isAlive()||thread2.isAlive()){ } System.out.println("finish"); }}
2. 对象锁:代码块形式
代码块锁就是常用的同步方法块,synchronized锁住的是它里面的对象,作用域就是synchonized{}里面的代码
public class SynchronizedObjectCodeBlock implements Runnable{ private static SynchronizedObjectCodeBlock instance=new SynchronizedObjectCodeBlock(); Object lock1=new Object(); @Override public void run() { synchronized (lock1){ System.out.println("我是对象锁的代码块形式。我叫"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"运行结束"); } } public static void main(String[] args){ Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); while(thread1.isAlive()||thread2.isAlive()){ } System.out.println("finish"); }}
3. 类锁:class形式
class形式说的是synchronized()括号里使用的锁是class对象,所谓class对象指得是java文件对应的一个java.lang.class对象,所有该类生成的对象共有这个class对象 类加载机制,所以这个锁锁住了这个类生成的所有对象
public class SynchronizedClassClass implements Runnable{ private static SynchronizedClassClass instance1=new SynchronizedClassClass(); private static SynchronizedClassClass instance2=new SynchronizedClassClass(); public void method(){ synchronized (SynchronizedClassClass.class){ System.out.println("我是类锁的形式之一:修饰.class。我叫"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"运行结束"); } } @Override public void run() { method(); } public static void main(String[] args) { Thread thread1 = new Thread(instance1); Thread thread2 = new Thread(instance2); thread1.start(); thread2.start(); while(thread1.isAlive()||thread2.isAlive()){ } System.out.println("finish"); }}
在这个案例中,存在两个SynchronizedClassClass对象,但是不能同时访问同步代码
4.类锁:static形式
static形式说的是static修饰synchronized修饰的方法,即static synchronized methodName,作用方法还是这个类的class对象
public class SynchronizedClassStatic implements Runnable{ private static SynchronizedClassStatic instance1=new SynchronizedClassStatic(); private static SynchronizedClassStatic instance2=new SynchronizedClassStatic(); public static synchronized void method(){ System.out.println("我是类锁的形式之一:加static修饰。我叫"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"运行结束"); } public void method2(){ System.out.println("我是非静态方法,我叫"+Thread.currentThread().getName()); } @Override public void run() { method(); method2(); } public static void main(String[] args) { Thread thread1 = new Thread(instance1); Thread thread2 = new Thread(instance2); thread1.start(); thread2.start(); while(thread1.isAlive()||thread2.isAlive()){ } System.out.println("finish"); }}
二、synchronized的原理
让我们从字节码来看看synchronized的神秘面纱, 我们反编译synchronized修饰object的java文件
public class Decompilation { private Object object=new Object(); public void insert(Thread thread){ synchronized (object){ } }}
反编译指令为 javap -c -v YourName.java
所以就是这个小小的Monitor Enter和monitorexit指令完成了同步操作,关于Monitor Enter和monitorexit的定义可以查看jvm文档 中的注释
先看看 Monitor Enter,注意紫色标注
再看看Monitor Exit这里就解释清楚为什么synchronized上的锁是可重入的,对于更深入的理解
重点还是提到的Monitor这个概念
我们再反编译synchronize修饰的同步方法,其结果是
与之前不一样,这里是在方法的访问标识上添加了ACC_SYNCHRONIZED,它在jvm文档中是这么解释大致意思就是当调用设置了 ACC_SYNCHRONIZED 的方法时,执行线程进入监视器(monitor),然后执行这个方法,方法执行完毕后退出监视器。在执行线程拥有监视器期间,没有其他线程可以进入这个方法.
同样,这里涉及了Monitor
2.1 深入Monitor
虽然HotSpot的JDK代码没有开元,但好在还有OpenJDK,大家有时间可以看看ObjectMonitor.hpp和ObjectMonitor.cpp,如果c语言功力不好的同学,看看注释,大致知道每个变量啥意思即可。
主要是_owner
,_recursions
,_entryList
,_waitSet
,此外还有header
这个对象头将对象和Monitor
联系起来。
_owner
顾名思义就是锁的拥有者,recursions
就是锁的进入次数,初始为0,而_entryList
是存放Blocked状态的线程的,waitSet
是存放Waiting状态的线程。
在HotSpot中,一个对象是在Heap中的存储布局有三个部分:对象头(Header),实例数据(Instance Data)以及对齐填充部分,而对象头一般由两个部分组成:MarkWord和类型指针,如果是数组对象,那么还有数组长度信息。
而MarkWord就是连接Monitor和对象的关键东西。它存储了对象运行时的一些数据,比如HashCode,GC年龄,锁的状态,线程所持有的锁等。
总之,monitor才是synchronized并发的关键,monitor是底层用cpp实现的一个对象,实现了锁的状态转换,获取释放等方法,通过markword与java对象联系一起,而markword是嵌入在java头部的。
三、synchornized的各种锁以及优化
3.1 锁的升级
从jdk1.6开始,synchronized锁有四种状态,级别由低到高是
无锁,偏向锁,轻量锁,重量锁
锁的升级过程是一个很麻烦的事情,本质就是如果发生了锁的竞争就升级锁,直到升级到重量锁为止,期间使用到了CAS和自旋来避免线程直接进入阻塞状态。有兴趣的同学可以看看《阿里巴巴java性能调优实战》这本书。
3.2 JIT 实现锁消除和锁粗化
锁消除的概念比较容易理解,就是如果编译器认定一个锁只会被单个线程访问,那么这个锁就可以被消除。而锁粗化,简单的说就是JIT动态编译时发现相邻的同步块使用的是同一个锁实例,那么就合并他们,避免频繁加锁释放锁。
3.3 减少锁的粒度
这是我们平时编程的时候,我们可以控制的,有的同学(比如我)图省事往往可以加对象锁的,直接加类锁,这样就是不地道的。
《阿里巴巴java性能调优实战》举例说明减少锁的粒度的好处,比如被抛弃的HashTable和新宠ConcurrentHashMap的转换,就是使用了减少锁的粒度方法。
关键词:
-
第134篇:解决浏览器的CORS跨域问题(CORS policy: Cross origin requests are only supported for p
好家伙,我继续尝试着将我的飞机大战使用ES6模块化分离开来,出了点问题1 出现问题:edge,chrome等一系列...
来源: 每日资讯:一些面试高频题目
Synchronized详解
第134篇:解决浏览器的CORS跨域问题(CORS policy: Cross origin requests are only supported for p
环球观速讯丨《生化危机4:重制版》DLC正在开发中 艾达王是你的了
每日快播:深圳暴雨致航班取消 旅客情绪崩溃 跪求起飞 机场回应
环球通讯!全明星的三大遗憾,成就了这场本土篮球盛宴的缺憾之美
【Visual Leak Detector】配置项 AggregateDuplicates
Python毕业设计推荐
实时焦点:RTX 4070定了!还是你们讨厌的192位显存
每日看点!彻底没救了!《Forspoken》发售2个月后:RTX 4090依旧无法60帧
【播资讯】100亿捐款建大学 曹德旺:对标美国斯坦福 每个学生补贴5万
每日信息:做出莫斯利安的光明乳业:掉队了
女员工请假做试管婴儿被拒遭辞退 法院判了:恢复合同
环球观察:Vue 核心(二)
观焦点:HDFS Short-Circuit Local Reads
货币市场日报:3月27日
热消息:4月10日上市 福特F-150猛禽烈焰风暴特别版官图发布 为中国市场而
能抄底了?一汽奥迪补贴经销商清库存 明星车型降价近10万
每日看点!马云回国首谈ChatGPT:机器只有“芯”而人有“心”
国产车赢麻了!报告:中国品牌占俄罗斯新车销量近40%
焦点信息:“高端家用车”?比亚迪汉DM-i试驾 极致的油耗和空间
天天视讯!国产两轮电动车龙头!雅迪2022年营收310亿创纪录:电动自行车销量大增
焦点!通胀压力缓解避险情绪收敛 日债收益率周一全线回升
世界速读:商品日报(3月27日):沪锡领涨纯碱09合约增仓上行 苹果大幅下挫跌超4%
速读:前备箱门锁失灵?特斯拉扩大召回进口Model S
京东方iPhone 15灵动岛屏被曝漏光 苹果搬来三星救火:提前生产
天天热点评!女子赏花站梨树枝头甩衣狂摇 拍摄者:花瓣掉落一地
观热点:女子吃自助餐将店内甲鱼煮食 网友:是个狠人
乌鲁木齐周生生黄金价格多少钱一克(2023年3月27日)
新动态:CodeIgnitor 3.0.x 之 db 类实现机制
第一次博客
环球热点评!小皮Windows web面板漏洞详解
世界观速讯丨【原型设计工具】上海道宁为您提供Justinmind,助力您在几分钟内形成原型,并现场测试,无需编写任何代码
女生从俄罗斯花2分钟回国吃麻辣烫 挑战全网最短留学距离:网友感慨真近
环球观点:文心一言升级版!百度发布企业级大模型服务平台“文心千帆”
当前速讯:太危险!女子驾驶保时捷玩具车上机动车道吓坏路人:自称为了好玩
承认造假丑闻!百年日企川崎重工形象崩塌:鞠躬道歉
资讯推荐:男子跑滴滴1单挣了3148元:光等待费就两千多元
环球要闻:从GPT-4、文心一言再到Copilot,AIGC卷出新赛道?
即时:【必须收藏】别再乱找TiDB 集群部署教程了,这篇保姆级教程来帮你!!| 博学谷狂野架构师
当前关注:C#多态性学习,虚方法、抽象方法、接口等用法举例
python中index()、find()方法
每日视点!便宜香港主机推荐
环球速递!秒变大屏平板!三星将推新款折叠手机:双铰链、三折叠
天天报道:专家评中国为何没跟上ChatGPT浪潮:0-1的事情没人做
电动车价格还得降 宁德钠离子电池今年量产:高寒地区突出优势
广汽埃安新车慢充失灵 车主:4S店给补偿 但协议他不想签
天天热推荐:日本声优网络发文吐槽外送被打翻 网友:小心隐私
天天精选!批量上传iOS应用程序截图的实用技巧
天天热头条丨OPPO发布新机|无感验证护航“黄牛党”退退退!
环球滚动:易基因:肠道菌群:早产儿出生后不同时间点肠道微生物定植的动态变化|项目文章
快播:Qt 博客汇总
天天热推荐:图片识别文字(批量图片文字查找分类)
普京称嫉妒的人才说俄依赖中国 欧洲应该想想自己
科创板收盘播报:科创50指数探底回升跌0.33% 软件服务类个股表现强势
甲醛滤芯永不更换!米家全效空气净化器评测:不仅除尘、还能杀死H1N1病毒
顺丰开通贵州茅台首条全货机航线 10余吨酒、茶特产首飞成功
每日资讯:飞机航班为何不卖站票?大V科普:并非航空公司良心
罕见5风扇设计!铭瑄RTX 4070 Ti MGG OC12G显卡图赏
三电升级、寿命翻倍!绿源液冷2.0系统升级上线:能骑十年
Transformer详解
全球速递!解决google翻译出错问题
世界通讯!【高端访谈】“开放的中国大市场蕴藏更多新机遇”——访马士基首席执行官柯文胜
以铜之名尽显千年风流
全球信息:打造中国ChatGPT 搜狗输入法之父马占凯加入王慧文AI团队
独一无二木星纹理见过么?一加11推出木星岩限定版:100%手工挑选
环球快看:曾被宣布“野外灭绝” 长江鲟时隔23年首次自然产卵
当前速读:ubuntu 使用vsftpd搭建FTP服务器
全球热议:6.824-lab2-Raft简述
环球滚动:Template模板类
全球讯息:【Visual Leak Detector】配置项 VLD
【速看料】火山引擎 DataTester:构建增长闭环,3-5 人即可搭建企业增长团队
【新要闻】曾因配料“双标”遭网友痛批 好丽友漏税22万被罚12万
全球时讯:空姐为美容注射玻尿酸:打进血管 险丧命
三星W799哪年上市的?三星W799可以安装微信吗?
诺基亚920还能用吗?诺基亚920手机参数
英雄联盟手游大师多少颗星上宗师?英雄联盟几级可以组队匹配?
总线上的音频设备前是感叹号是什么原因?总线上的音频设备前是感叹号怎么处理?
华为合约机是什么意思?华为合约机和官方标配区别有哪些?
C#遍历指定文件夹中所有文件的3种方法
天天热议:Sed 备忘清单_开发速查表分享
史上最严奶粉新国标实施逾月 贝因美又一款二注奶粉上新 哪些信号值得关注?
热推荐:甘肃将为兰州牛肉拉面立法 网友:建议牛肉有重量标准
热点在线丨《原神》地位不保?开放世界游戏《鸣潮》实机画面公布
环球简讯:曹德旺:大学生去送外卖 和在学校没学到东西有关
任性钻“夹缝”被撞旋转1080° 司机甩锅:都怪后车开太快了
当前快播:判赔370万!中创新航回应不正当竞争案判决:未曾挖角宁德时代 将上诉
天天百事通!OpenIddict使用教程
流量分析入门
全球观速讯丨MySql随笔记基础
【高端访谈】强化城投债与量化领域主动管理 打造私募“固收+”独特策略——专访国恩资本董事总经理杨先哲
通讯!旃怎么读音(旃怎么读)
36年前电脑用上AI:IBM 5155运行ChatGPT是什么样?
环球看热讯:清晰度和功耗完美平衡!真我GT Neo5系列宣布告别1080P:普及1.5K屏
罕见!超级火流星划过北京夜空被拍下:彩色拖尾 爆裂闪光
每日快讯!《生化危机4:重制版》阿什莉模型展示:物理晃动效果很优秀
全球快看点丨车评人曝奔驰4S维修黑幕:一个迈巴赫大灯小20万 故意损坏夸大车损
即时:数据库系统原理之SQL与关系数据库基本操作
每日焦点!【解答】如何保障ETL过程的数据正确性。这个过程会产生哪些问题?
世界要闻:DHCP snooping