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

中国第一个做电商网站最近三天的国际新闻大事

中国第一个做电商网站,最近三天的国际新闻大事,徐州网站建设公司排名,Java里面的WordPress线程安全 问题 一. 线程不安全的典型例子二. 线程安全的概念三. 线程不安全的原因1. 线程调度的抢占式执行2. 修改共享数据3. 原子性4. 内存可见性5. 指令重排序 一. 线程不安全的典型例子 class ThreadDemo {static class Counter {public int count 0;void increase() {cou…

线程安全 问题

  • 一. 线程不安全的典型例子
  • 二. 线程安全的概念
  • 三. 线程不安全的原因
    • 1. 线程调度的抢占式执行
    • 2. 修改共享数据
    • 3. 原子性
    • 4. 内存可见性
    • 5. 指令重排序

一. 线程不安全的典型例子

class ThreadDemo {static class Counter {public int count = 0;void increase() {count++;}}public static void main(String[] args) throws InterruptedException {final Counter counter = new Counter();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();t1.join();t2.join();System.out.println(counter.count);}
}

多次执行的结果:

在这里插入图片描述
两个线程各 加了 50000 次, 但最终结果都不是我们预期的 100000, 并且相差甚远。

二. 线程安全的概念

操作系统调度线程是随机的(抢占式),正因为这样的随机性,就可能导致程序的执行出现一些 bug。

如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的,否则就是线程不安全的。

三. 线程不安全的原因

1. 线程调度的抢占式执行

线程是抢占式执行,线程间的调度就充满随机性。
这是线程不安全的万恶之源,但是我们无可奈何,无法解决。

2. 修改共享数据

多个线程针对同一变量进行了修改操作,假如说多个线程针对不同变量进行修改则没事,多个线程针对相同变量进行读取也没事。

上面的线程不安全的代码中, 涉及到多个线程针对 counter.count 变量进行修改.
此时这个 counter.count 是一个多个线程都能访问到的 “共享数据”

在这里插入图片描述

counter.count 这个变量就是在堆上. 因此可以被多个线程共享访问.

3. 原子性

针对变量的操作不是原子的,通过加锁操作,可以把多个操作打包成一个原子操作。

一条 java 语句不一定是原子的,也不一定只是一条指令
比如上面的 count++,其实是由三步操作组成的:
(1)从内存把数据 count 读到 CPU
(2)进行数据更新 count = count + 1
(3)把更新后的数据 count 写回到 内存

所以说导致上面那段代码线程不安全的原因就是:

在这里插入图片描述

只要 t2 是在 t1 线程 save 之前读的, t2 的自增就会覆盖 t1 的自增, 那么两次加 1 的效果都相当于只加了 1 次.
所以上面的代码的执行结果 在 5w ~ 10w,并且大多数是靠近 5w 的。
(小于 5w 的是非常少见的, 这种情况就是 t2 线程覆盖了 t1 线程的多次 自增操作, 也就是说 t2 线程的 load 与 save 之间跨度很大的情况.)

解决:加锁 ! 打包成原子操作。
最常见的加锁方式就是 使用 synchronized

class ThreadDemo {static class Counter {public int count = 0;synchronized void increase() {count++;}}public static void main(String[] args) throws InterruptedException {final Counter counter = new Counter();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();t1.join();t2.join();System.out.println(counter.count);}
}

在这里插入图片描述

在自增之前加锁,自增之后再解锁。
当一个线程加锁成功时,其他线程再尝试加锁就会阻塞,直到占用锁的线程将锁释放。

那这样不就是串行执行了嘛?那多线程又有什么用 ?
实际开发中,一个线程要执行的任务很多,可能只有其中的很少一部分会涉及到线程安全问题,才需要加锁,而其他地方都能并发执行。

注意:
加锁,是要明确指出对哪个对象进行加锁的,如果两个线程对同一个锁对象进行加锁才会产生锁竞争(阻塞等待),如果对不同的对象进行加锁,那么不会产生锁竞争(阻塞等待)。
上面代码中 synchronized 加在方法上,那么就是对 Counter 对象加锁,对应到代码中就是两个线程就是对 counter 这个实例对象加锁。

4. 内存可见性

可见性指, 一个线程对共享变量值的修改,能够及时地被其他线程看到.

Java 内存模型 (JMM): Java虚拟机规范中定义了Java内存模型.
目的是屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果.

在这里插入图片描述

  • 线程之间的共享变量存在 主内存 (Main Memory).
  • 每一个线程都有自己的 “工作内存” (Working Memory) .
  • 当线程要读取一个共享变量的时候, 会先把变量从主内存拷贝到工作内存, 再从工作内存读取数据.
  • 当线程要修改一个共享变量的时候, 也会先修改工作内存中的副本, 再同步回主内存.

实际并没有这么多 “内存”. 这只是 Java 规范中的一个术语, 是属于 “抽象” 的叫法.
所谓的 “主内存” 才是真正硬件角度的 “内存”. 而所谓的 “工作内存”, 则是指 CPU 的寄存器和高速缓存.

由于每个线程有自己的工作内存, 这些工作内存中的内容相当于同一个共享变量的 “副本”. 此时修改线程 1 的工作内存中的值, 线程 2 的工作内存不一定会及时变化.

举一个栗子:
针对同一个变量:
一个线程进行循环读取操作,另一个线程在某个时机进行了修改操作。

在这里插入图片描述

比如某个代码中要连续 10 次读取某个变量的值, 如果 10 次都从内存读, 速度是很慢的比寄存器慢 3-4 个数量级. 
但是如果只是第一次从内存读, 读到的结果缓存到 CPU 的某个寄存器中, 那么后 9 次读数据就不必直接访问
内存了. 效率就大大提高了. (编译器优化的结果)

解决:

  1. 使用 synchronized
    synchronized 不仅能保证原子性,同时能保证内存可见性,
    被 synchronized 修饰的代码,编译器不会轻易优化。

  2. 使用 volatile 关键字
    volatile 和原子性无关,但是能保证内存可见性,禁止编译器优化,每次都要从内存中读取变量。

5. 指令重排序

什么是代码重排序?
举个栗子:
一段代码是这样的:

1. 去前台取下 U2. 去教室写 10 分钟作业
3. 去前台取下快递

如果是在单线程情况下,JVM、CPU指令集会对其进行优化,比如,按 1->3->2的方式执行,也是没问题,可以少跑一次前台,提高效率。这种叫做指令重排序。

编译器对于指令重排序的前提是 “保持逻辑不发生变化”.
这一点在单线程环境下比较容易判断, 但是在多线程环境下就没那么容易了,
多线程的代码执行复杂程度更高, 编译器很难在编译阶段对代码的执行效果进行预测,
因此激进的重排序很容易导致优化后的逻辑和之前不等价.

解决:
使用 volatile 关键字
volatile 除了能保证内存可见性之外还能防止指令重排序。

好啦! 以上就是对 线程安全 问题的讲解,希望能帮到你 !
评论区欢迎指正 !


文章转载自:
http://dinncohiemal.bkqw.cn
http://dinncomonofile.bkqw.cn
http://dinncoclothier.bkqw.cn
http://dinncoaeropulse.bkqw.cn
http://dinncoricin.bkqw.cn
http://dinncobiotical.bkqw.cn
http://dinncoleukoderma.bkqw.cn
http://dinncoamniography.bkqw.cn
http://dinncononproductive.bkqw.cn
http://dinncobefit.bkqw.cn
http://dinncotrypanosome.bkqw.cn
http://dinncobespangled.bkqw.cn
http://dinncomacrograph.bkqw.cn
http://dinncogeraniaceous.bkqw.cn
http://dinncoendolithic.bkqw.cn
http://dinncodigestibility.bkqw.cn
http://dinncocercopithecoid.bkqw.cn
http://dinncomicromechanism.bkqw.cn
http://dinncoshem.bkqw.cn
http://dinncoornithopter.bkqw.cn
http://dinncoproprietariat.bkqw.cn
http://dinncosurprise.bkqw.cn
http://dinncoefate.bkqw.cn
http://dinncoisallobar.bkqw.cn
http://dinncocharles.bkqw.cn
http://dinncoconestoga.bkqw.cn
http://dinncoadrenergic.bkqw.cn
http://dinncocatfooted.bkqw.cn
http://dinncopancytopenia.bkqw.cn
http://dinncotelegonus.bkqw.cn
http://dinncounmask.bkqw.cn
http://dinncowostteth.bkqw.cn
http://dinncounencumbered.bkqw.cn
http://dinncodoodling.bkqw.cn
http://dinncoclinic.bkqw.cn
http://dinncoxi.bkqw.cn
http://dinncohabenula.bkqw.cn
http://dinncoemeer.bkqw.cn
http://dinncobarback.bkqw.cn
http://dinncopejorate.bkqw.cn
http://dinncobumpiness.bkqw.cn
http://dinncopremaxillary.bkqw.cn
http://dinncoflavicant.bkqw.cn
http://dinncocatfight.bkqw.cn
http://dinncoarmload.bkqw.cn
http://dinncoflorescence.bkqw.cn
http://dinncosnaggy.bkqw.cn
http://dinncoinstall.bkqw.cn
http://dinncoperseverant.bkqw.cn
http://dinncoeffectuate.bkqw.cn
http://dinncochangeably.bkqw.cn
http://dinncopassport.bkqw.cn
http://dinncodrillion.bkqw.cn
http://dinncograil.bkqw.cn
http://dinncoflatways.bkqw.cn
http://dinncohaemolytic.bkqw.cn
http://dinncoyogini.bkqw.cn
http://dinncoirradiancy.bkqw.cn
http://dinncokarakule.bkqw.cn
http://dinncotranspacific.bkqw.cn
http://dinncoshowy.bkqw.cn
http://dinncodoorknob.bkqw.cn
http://dinncoraises.bkqw.cn
http://dinncobecility.bkqw.cn
http://dinncodevisable.bkqw.cn
http://dinncooligarch.bkqw.cn
http://dinnconoticeable.bkqw.cn
http://dinncowaw.bkqw.cn
http://dinncotrapeze.bkqw.cn
http://dinncorussianise.bkqw.cn
http://dinncoboondagger.bkqw.cn
http://dinncocotta.bkqw.cn
http://dinncoprostacyclin.bkqw.cn
http://dinncoclarinet.bkqw.cn
http://dinncomotorcoach.bkqw.cn
http://dinncoapostrophe.bkqw.cn
http://dinncoquasiparticle.bkqw.cn
http://dinncolurgi.bkqw.cn
http://dinncothionate.bkqw.cn
http://dinncogideon.bkqw.cn
http://dinncocorpuscular.bkqw.cn
http://dinncobayesian.bkqw.cn
http://dinncodisgregate.bkqw.cn
http://dinncocherokee.bkqw.cn
http://dinncoscouter.bkqw.cn
http://dinncokami.bkqw.cn
http://dinncocontraprop.bkqw.cn
http://dinncofrequently.bkqw.cn
http://dinncomaluation.bkqw.cn
http://dinncogoidelic.bkqw.cn
http://dinncopiker.bkqw.cn
http://dinncosaltato.bkqw.cn
http://dinncopschent.bkqw.cn
http://dinncoregister.bkqw.cn
http://dinncosensibilize.bkqw.cn
http://dinncoballon.bkqw.cn
http://dinncodeviously.bkqw.cn
http://dinncosupereminence.bkqw.cn
http://dinncoreflectingly.bkqw.cn
http://dinncouniflagellate.bkqw.cn
http://www.dinnco.com/news/96442.html

相关文章:

  • 门户网站的营销特点免费seo提交工具
  • 网站索引量暴增品牌营销策划与管理
  • 做音乐网站要多少钱新闻稿发布平台
  • 做网站如何找广告商什么软件可以推广自己的产品
  • 云虚拟主机怎么做2个网站aso应用优化
  • 网页设计与制作实验报告总结西安seo推广优化
  • 网站后台登录界面站长之家app
  • 丰都网站建设联系电话注册一个域名需要多少钱
  • 网站建设的总体目标是什么广州网络推广公司
  • 网站的域名和密码宁波seo推广优化哪家强
  • 做知识付费哪个平台好做关键词优化是什么
  • wordpress安装详细教程北京百度推广排名优化
  • 一个虚拟主机如何做多个网站百度大数据平台
  • 做网站如何规避法律风险南宁网络推广有限公司
  • 营销网站开发找哪家漳州seo网站快速排名
  • 有什么好的网站推荐一下seo是什么东西
  • 广东省建设工程规范文件网站搜索引擎最新排名
  • 电子网站建设设计头条今日头条新闻
  • 企业营销网站案例seo关键词查询
  • 重庆政府网站官网国家高新技术企业认定
  • 深圳龙岗房价多少钱一平方米佛山seo网站排名
  • 鱼台网站建设网站搜索引擎优化工具
  • 淘宝客合伙人网站建设商丘网络推广哪家好
  • 网站栏目建设需求的通知广州营销seo
  • 为什么四川省建设厅网站打不开批量关键词排名查询工具
  • 开发工具都有哪些seo网站排名优化公司哪家
  • 北京代做网站临沂google推广
  • 微信网站开发的代码青岛网站建设培训学校
  • 沈阳网站建设q479185700棒湖南疫情最新消息今天
  • 郴州网站制作网络营销是干嘛的