当前位置: 首页 > news >正文

茶叶网站模板下载wordpress高亮代码添加行号

茶叶网站模板下载,wordpress高亮代码添加行号,做资金盘网站,个性婚纱摄影多线程篇-线程安全-原子性、可见性、有序性解析 在程序中使用多线程的目的是什么#xff1f; 1、提高效率#xff0c;增加任务的吞吐量 2、提升CPU等资源的利用率#xff0c;减少CPU的空转 多线程的应用在日常开发中很多#xff0c;带来了很多的便利#xff0c;让我们以前…多线程篇-线程安全-原子性、可见性、有序性解析 在程序中使用多线程的目的是什么 1、提高效率增加任务的吞吐量 2、提升CPU等资源的利用率减少CPU的空转 多线程的应用在日常开发中很多带来了很多的便利让我们以前研究下在多线程场景中要注意问题吧一般主要从这三个方面考虑 1、原子性 2、可见性 3、有序性 如果不能保证原子性、可见性和顺序性会有什么问题这些问题怎么解决呢让我们一起来看下 一、原子性 原子性的操作是不可被中断的一个或一系列操作。 个人理解严格的原子性的操作其他线程获取操作的变量时只能获取操作前的变量值和操作后的变量值不能获取到操作过程中的中间值在操作过程中其他操作需要获取变量值需要进入阻塞状态等待操作结束。 如果不能保证原子性会有什么问题呢 让我们一块看一个简单例子吧 首先写一个简单的线程代码如下 public class ThreadDemo implements Runnable{int no 0;Overridepublic void run() {no;System.out.println(no);}public static void main(String[] args){ThreadDemo demo new ThreadDemo();for(int i0;i1000;i){Thread task new Thread(demo);task.start();}} } Main函数中启动了1000个线程每个线程都对no进行了一次1操作理想情况下no最后的结果应该是1000可是我的运行最终结果只有996执行了1000次1操作最后的结果为什么不是1000呢这就要说到no操作不是原子的问题了no可见性的问题在下一个小结讨论 先对no这个操作分解可以分为三步取值加一赋值这三个操作都是原子的不过合在一起就不行了。两个线程A、B一起来操作nono初始值是1,线程A读取no值是1然后做no1这时线程B对 no取值还是1然后A将2赋值给noB操作no1结果是2也将2赋值给no。对1做了两次1操作最后结果是2。这个过程可以参考下图 所以需要保证这种不可分割操作的原子性那要怎么做才能保证原子性呢有两种方式 1、加锁synchronized保证同一时间只有一个线程操作变量其他线程需等待操作结束才能使用临界资源 2、使用CAS操作变量计算前保留一份旧值a计算完成后结果值为b把b刷到内存之前先比较a是否和内存中变量一致如果一致就把内存中的变量赋值为b不一样重新获取内存中变量值重复一遍操作一直到a和内存中一致操作结束。 Lock和原子类AtomicInteger等是通过使用unsafe的compareAndSwap方法实现CAS操作保证原子性的。 二、可见性 线程变量的可见性问题需要从操作系统的CPU、缓存、内存的矛盾开始说起。读写性能上 CPU缓存内存I/O。CPU/缓存/内存的结构看下图。 CPU和内存之间隔着缓存和CPU寄存器。缓存还分为一级、二级、三级缓存。CPU的读写性能上要大于内存为了提高效率会将数据先取到缓存中CPU处理完数据后会先放到缓存中然后同步到内存中。 如果不理解CPU缓存这部分内容的话可以简单的认为每个线程都有自己的本地工作内存变量会先缓存到本地工作内存中使用修改后会先修改工作内存中的存储然后在同步到主内存中。结构如下图 这种内存结构会引起什么问题呢现在有一个变量var线程A对var做了一次修改刚放到缓存工作内存还未同步到内存时另外一个线程B也来使用var读取到的还是var未修改值。 共享的变量需要保证可见性怎么保证共享变量的可见性呢 1、加锁加锁是万能的操作synchronized和Lock都可以保证。 线程在加锁时会清空工作内存中共享变量的值共享变量使用是需要从主内存中重新获取。 线程解锁是会把共享变量重新刷新到主内存中。 2、使用volatile修饰共享变量volatile修饰的共享变量在修改后会立即被更新到内存中其他线程使用共享变量会去内存中读取 优先使用volatile来解决可见性问题加锁需要消耗的资源太多。 三、有序性 为了优化程序性能编译器、处理器和运行时会对代码指令进行重排重排过程中会遵循as-if-serial语义即不影响单线程的运行结果。 扩展一下 指令重排为什么会提高程序性能呢我个人理解是CPU是多核处理的为了保证处理器资源的充分利用对代码指令进行乱序处理即可以多个处理器并行处理指令防止不相关的指令需要等待上一个指令结束才能开始。 代码执行顺序被重排会是什么效果呢举个简单例子 int a 0;a2;int b 1;int c ab; 这段代码中变量a和b 是相互不影响的优化后可以是如下代码只要保证执行结果不变有依赖的变量c在变量a和b之后处理即可 int b 1;int a 0;a2;int c ab; 在单线程中这样是没有问题的如果是多线程呢看下如下代码 public class Task {static Object val null;static boolean finish false;public static void main(String[] args){Runnable task1 new Runnable() {Overridepublic void run() {if(finish){System.out.println(val.toString());}}};Runnable task2 new Runnable() {Overridepublic void run() {val new Object();finish true;}};} } 分别创建两个任务task1和task2,他们共享两个变量val和finish按现在的顺序执行的话task1不会出现val为null时被使用的情况。不过进行了指令重排之后呢task2中val和finish操作顺序调整对单线程来说是没有任何影响的所以task2的代码可能会变成 Overridepublic void run() {finish true;val new Object();} 这样task1中就会出现finish为trueval为null的情况了。 那么怎么保证多个线程中的代码顺序一致性呢 1、加锁还是加锁synchronized和Lock保证同一时刻只有一个线程进行操作 2、使用volatile修饰变量在JMM中volatile的读和写都会插入内存屏障来禁止处理器的重排 这样原子性、可见性、有序性就基本讲完了其中有很多的知识点没有详细的说例如 CAS、volatile、synchronized、lock等等这些会在后边的文章中慢慢研究。 注如果弄不清楚原子性和可见性的区别只要记住下边两点内容 1、原子性针对完整的操作过程其他操作只能获取操作前或操作后的变量数据 2、可见性主要是变量修改变量修改后马上刷新到内存中而其他线程能感知到变量的修改
http://www.sadfv.cn/news/70265/

相关文章:

  • 阿里云网站建设如何体彩足球竞彩比赛结果韩国比分
  • 学习做网站需要多久php网站后台开发教程
  • 网站链接数怎么做陕西建设厅官方网站
  • 电子商务网站建设题库及答案黄骅百度贴吧招聘
  • 昆明专业网站建设公司稳稳在哪个网站做的消防直播
  • 山东圣大建设集团网站网站开发商城实例
  • 如何做英文网站的中文网中国建设机械教育网官方网站
  • 广州站在哪个区快速收录网站内页
  • 一个网站不兼容ie怎么做win7系统优化工具
  • 摄影网站的制作做导航网站怎么赚钱
  • 佛山建站公司哪家好张家港优化网站seo
  • 德邦物流公司现代物流网站建设与开发从化网站开发
  • 教学网站建设计划英语卷子哪个网站可以做
  • 服务器2003怎么做网站20m做网站
  • 服务器做的网站 怎么使用内网建站教程
  • 网站搭建 成都江苏省城乡建设部网站首页
  • 西安市做网站的公司广州网络引流公司
  • 企业互联网网站定位百度网页版登录入口官网
  • 响应式电商网站网站使用网络图片做素材 侵权吗
  • 网站建设与维护培训做网站多少钱赚钱吗
  • 东莞网站建设_东莞网页设计公司网站优化要怎么做
  • 网站建议怎么写珠海网站制作价格
  • 潍坊网站建设怎样最新企业网站
  • 同性做视频网站烟台建网站公司
  • 爱网站排行榜查看自己网站访问量
  • 网站开发课wordpress文章id修改
  • 黑龙江省住房和建设厅网站wordpress主题无法上传
  • 佛山新网站建设代理商南昌网站建设方案服务
  • 做悬浮导航的网站个人站长做网站需要多少钱
  • 鹤壁建设网站怎么做网站的二维码