暮年|20年架构师深入讲解java多线程与高并发:volatile与CAS,涨薪5K( 四 )
<100; i++){new Thread(()->System.out.println(Mgr03.getInstance().hashCode())).start();}}}}三个步骤顺序有严格的规定吗 , 在JVM里面规定了八种原则 , 除了这些之外其他的指令都可以有重排序 , 保证原子性只是保证这些操作必须要么都完成之后其他才能访问 , 但是保证了原子性和保证重排序是两回事儿
到现在为止 , volatile的两个含义已经说完了 。
下面这个程序 , 如果不加volatile是一定会有问题的 , 结果是到不了10万的 , 原因很简单 , count值改变之后只是被别的线程所看见 , 但是光看见没用 , count++本身它不是一个原子性的操作 , 所以说volatile保证线程的可见性 , 并不能替代synchronized , 保证不了原子性 。 要想解决这个问题 , 加上synchronized 。
/*** volatile并不能保证多个线程共同修改running变量时所带来的的不一致问题 , 也就是说volatile不能替代synchronized* 运行下面的程序 , 并分析结果* @author mashibing*/package com.mashibing.juc.c_013;import java.util.ArrayList;import java.util.List;public class T{volatile int count = 0;/*synchronized*/ void m(){ for (int i=0; i<10000; i++ ) count++; }public static void main(String[] args){T t=new T();List threads = new ArrayList<>();for( int i=0; i<10; i++){threads.forEach((o)->{try{o.join();}catch(InterruptedException e){e.printStackTrace();}});System.out.println(t.count);}}}
好 , 我们来看锁优化的一些问题 , 这个锁优化内容非常多啊 , 线程这块儿的内容也特别好玩儿 , 按顺序来讲是可能是1、2、3、4、5、6、7这样的内容 , 但是你要按照优化来讲 , 它这些优化可能会分布在不同的这个步骤之上 , 所以讲到某个优化的问题的时候我们就谈一次 , 讲到就谈一次 。
锁优化其中有一个叫做把锁粒度变细, 还有一个叫把锁粒度变粗 , 其实说的是一回事儿 , 什么意思呢 , 作为synchronized来说你这个锁呢征用不是很剧烈的前提下 , 你这个锁呢 , 粒度最好还是小一些 。
下面程序是什么意思 , 如果是说m1方法他前面有一堆业务逻辑 , 后面有一堆业务逻辑 , 这个业务逻辑我用sleep来模拟了它 , 那么中间是你需要加锁的代码 , 那这个时候你不应该把锁加在整个方法上 , 只应该加在count++上(参见m2) , 这很简单就叫做锁的细化 。 那什么时候需要将锁粗化呢 , 在征用特别频繁 , 由于你锁的粒度越变越细 , 好多小的细锁跑在你这个上面 , 这个方法 , 或者某一段业务逻辑里头 , 好 , 那你干脆不如弄成一把大锁 , 他的征用反而就没有那么频繁了 , 程序写的好 , 不会发生死锁 。
/*** synchronized优化* 同步代码块中的语句越少越好* 比较m1和m2* @author mashibing*/package com.mashibing.juc.c_016_LockOptimization;import java.util.concurrent.TimeUnit;public class FineCoarseLock {int count = 0;synchronized void m1() {//do sth need not synctry {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}//业务逻辑中只有下面这句需要sync , 这时不应该给整个方法上锁count ++;//do sth need not synctry {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}}void m2() {//do sth need not synctry {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}//业务逻辑中只有下面这句需要sync , 这时不应该给整个方法上锁//采用细粒度的锁 , 可以使线程争用时间变短 , 从而提高效率synchronized(this) {count ++;}//do sth need not synctry {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}}}
- 问董秘|上证指数年涨幅为8.01%,公司所属...,投资者提问:截止2020年7月29日
- 问董秘|请问对贵公司有哪些积极的影响?对...,投资者提问:2020年一季度国际油价大跌
- NG视频|中国细胞生物学学会2020年度实验室开放日科普活动优秀奖评审结果
- 前瞻产业研究院|2020年中国工业清洗剂行业市场现状及发展趋势分析 环保型清洗剂需求正加速增长
- 8月|2020年拉萨雪顿节活动安排出炉,约起!
- 预警|北京市2020年8月3日10时30分发布高温蓝色预警信号
- 同比|水井坊2020年上半年业绩降七成 去库存真的容易吗?
- [小鹏]如期实现大规模交付 小鹏P7七月交付1641台
- 【】2020年我国北斗卫星导航产业产值有望超4000亿
- 【】菱农晨曦中采菱