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

淄博做网站建设网站seo推广营销

淄博做网站建设,网站seo推广营销,自己做的网站加载慢,公司网站空间✨个人主页:bit me👇 ✨当前专栏:Java EE初阶👇 ✨每日一语:低头赶路,敬事如仪;自知自心,其路则明。 目 录🍸一. 线程不安全🍹二. 线程不安全的原因&#x1f…

请添加图片描述

✨个人主页:bit me👇
✨当前专栏:Java EE初阶👇
✨每日一语:低头赶路,敬事如仪;自知自心,其路则明。

目 录

  • 🍸一. 线程不安全
  • 🍹二. 线程不安全的原因

🍸一. 线程不安全

多线程编程,最重要,也是最困难的问题就是线程安全问题,它的万恶之源,罪魁祸首就是调度器的随机调度 / 抢占式执行 这个过程

线程不安全:在随机调度之下,程序执行有多种可能,其中的某些可能导致代码出现了 bug ,线程不安全 / 线程安全问题

例如:两个线程对一个变量进行并发的自增(创建俩线程,让这俩线程同时并发的对一个变量,自增 5w 次,最终预期能一共自增 10w 次)

//创建俩线程,让这俩线程同时并发的对一个变量,自增 5w 次,最终预期能一共自增 10w 次
class Counter{//用来保存计数的变量public int count;public void increase(){count++;}
}
public class Demo14 {//这个实例用来进行累加public static Counter counter = new Counter();public static void main(String[] args) {Thread t1 = new Thread(()->{for (int i = 0; i < 50000; i++) {counter.increase();}});Thread t2 = new Thread(()->{for (int i = 0; i < 50000; i++) {counter.increase();}});t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("count: " + counter.count);}
}

运行结果:

在这里插入图片描述

再运行一次:

在这里插入图片描述

发现随机调度顺序不一样,结果也就不一样

那上面的 bug 如何出现的?

执行一段代码,需要让 CPU 把对应的指令从内存中读取出来,然后再执行
 
像 count++ 一行代码,对应三个机器指令

  • 1.从内存读取数据到 CPU(load)
  • 2.在 CPU 寄存器中,完成加法运算(add)
  • 3.把寄存器的数据写回到内存中(sava)

指令的排序方式:

在这里插入图片描述

在这里插入图片描述

上述两种指令的排序方式恰好能到 2 。但是还有许许多多的排列组合方式,就都不一定了。

在这里插入图片描述

此时总和就是 1 了

在这里插入图片描述

这些还有许许多多就不在此举例了

根据上述的总结,俩种极端情况就是 5w 和 10w 。然后其他的情况就是 5w 和 10w 之间了。

拓展:

操作系统中的随机调度严格意义上来说其实不是 “随机调度” 。在内部他有自己的一套调度过程,我们不需要理解这个过程,了解了也无法改变这个调度。

 

🍹二. 线程不安全的原因

1. 操作系统的随机调度 / 抢占式执行。罪魁祸首,万恶之源
2. 多个线程修改同一个变量。三个条件缺一不可,别的情况都没事儿】(所以写代码中可以针对这三个点进行改变进行规避,但是范围有限,不是所有的场景都可以规避掉)
3. 有些修改操作,不是原子的!不可拆分的最小单位,就叫原子

通过 = 来修改,= 只对应一条机器指令,视为是原子的
通过 ++ 来修改,++ 对应三条机器指令,则不是原子的

什么是原子性?
 
我们把一段代码想象成一个房间,每个线程就是要进入这个房间的人。如果没有任何机制保证,A进入房间之后,还没有出来;B 是不是也可以进入房间,打断 A 在房间里的隐私。这个就是不具备原子性的。
 
那我们应该如何解决这个问题呢?是不是只要给房间加一把锁,A 进去就把门锁上,其他人是不是就进不来了。这样就保证了这段代码的原子性了。(后续详解关于锁)
 
后果:如果一个线程正在对一个变量操作,中途其他线程插入进来了,如果这个操作被打断了,结果就可能是错误的。

4. 内存可见性,引起的线程安全问题。内存改了,但是在优化的背景下,读不到看不见

例如一个线程读,一个线程修改:线程 1 LOAD 之后需要进行 TEST ,然后继续 LOAD 再继续 TEST ,这样循环走下去,但是,在程序运行过程中,可能会涉及到一个操作 “优化” (可能是编译器 Javac,也可能是 JVM Java,也可能是操作系统),由于 LOAD 读的操作太慢,反复读,每次读到的数据都是一样的,JVM 就对此做出了优化,不需要重复在内存中读取了,直接就重复用第一次从内存读到寄存器的数据就好了,此时在优化之后,线程 2 突然写了一个数据,由于线程 1 已经优化成读寄存器了,因此线程 2 的修改线程 1 感知不到。
 
上述优化在单线程环境下没问题,但是多线程情况下就可能产生问题,多线程环境太复杂,编译器/JVM/操作系统进行优化的时候就可能产生误判!!!针对这个问题,Java 引入了 volatile 关键字,让程序猿手动禁止编译器针对某个变量进行上述优化!

5. 指令重排序。调整代码执行顺序

也是编译器 / JVM / 操作系统优化
 
优化在单线程环境下没问题,但是多线程情况下就可能产生问题,例如 Test t = new Test(); 在底层就有三个步骤:

  1. 创建内存空间
  2. 往这个内存空间上构造一个对象
  3. 把这个内存的引用赋值给 t

 
此处就容易出现指令重排序引入的问题,2 和 3 的顺序是可以调换的,在单线程下调换这俩是没影响的,多线程下就不行了。例如我们俩线程,第一个线程按照先 2 后 3 的顺序,另一个线程尝试读取 t 的引用,当第二个线程读到 t 为非 null 的时候,此时 t 就一定是一个有效对象!!!如果是按照先 3 后 2 的顺序,第二个线程读到 t 为非 null 的时候,仍然可能是一个无效对象!!!

http://www.fp688.cn/news/160757.html

相关文章:

  • 要怎么做自己的网站视频教学英国搜索引擎
  • 网站开发结构有网站推广关键词工具
  • 企业服务平台是做什么的seo推广培训班
  • 青岛气象站建站时间网页优化建议
  • 毕设做桌面软件 网站seo百度关键词优化软件
  • 环保网站建设开发站长工具综合查询
  • 网站建设太金手指六六十自动发外链工具
  • 网站建设网站维护移动惠生活app下载网址
  • tomcat做网站seo优化名词解释
  • 常德网站建设全域云防疫管控优化措施
  • 网站加载不出来是什么原因大兵seo博客
  • 毕设做网站工作量够吗qq群推广
  • 太原市给企业做网站海外推广
  • 门户网站开发合同网页制作软件
  • 在县城做哪个招聘网站比较赚钱今日油价最新
  • 怎么做自适应的网站百度站长平台链接提交
  • 网站页面设计客服富阳seo关键词优化
  • 山西省建设厅官网站百度快速查询
  • 重庆住房和城乡建设部网站的打印准考证宁波优化系统
  • 如何由网页生成网站平台推广是什么
  • 日ip5000的网站怎么做站长推广网
  • 福建有没有网站做一件代发网站推广软件有哪些
  • 如何将自己做网站放上网下列哪些店铺适合交换友情链接
  • 北京做网站比较有名的公司有哪些企业培训体系搭建
  • 网站建设一般好久到期怎样在百度上做广告推广
  • 网站搭建后台宁波关键词优化企业网站建设
  • 做网站点击软件百度关键词优化点击 教程
  • 赣州建网站做网站怎么赚钱
  • No酒类网站建设seo培训价格
  • 企业网站建设联系电话网络推广宣传方式