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

政府网站集约化平台建设是知乎推广

政府网站集约化平台建设是,知乎推广,可靠的坪山网站建设,模板网站有利于做seo吗在开始讲解线程安全之前我们先来回顾一下我们学了那些东西了: 1. 线程和进程的认识 2. Thread 类的基本用法 3. 简单认识线程状态 4. 初见线程安全 上一章结束时看了一眼线程安全问题,本章将针对这个重点讲解。 一个代码在单线程中能够安全执行&am…

在开始讲解线程安全之前我们先来回顾一下我们学了那些东西了:

1. 线程和进程的认识

2. Thread 类的基本用法

3. 简单认识线程状态

4. 初见线程安全

上一章结束时看了一眼线程安全问题,本章将针对这个重点讲解。

一个代码在单线程中能够安全执行,但是在多线程中就容易出现错误;其本质原因就是线程在系统中的调度是无序的 / 抢占式执行的。

再看一眼上一章末尾的题,两个线程各执行 5w 次自增操作,最后的结果为什么是一个小于 10w 的随机数。

上节课也画了图:

 线程不安全的原因

我们在这里讨论一下照成线程不安全的原因有哪些?

  1. 多线程的抢占式执行(罪魁祸首)
  2. 多个线程修改同一个变量 【如果是一个线程修改一个变量 => 安全】【多个线程读取一个变量 => 安全】【多个线程修改不同变量 => 安全】
  3. 修改操作不是原子的 
  4. 内存可见性引起的线程不安全
  5. 指令重排序引起的线程不安全

那么我们就开始本章内容的讲解

对于 多线程的抢占式执行多个线程修改同一个变量 这两点不是我们能够改变的,我们就直接跳过,直接看第三条

修改操作不是原子的 

这里说到的原子性,数据库中 事物的原子性 是一个概念, 原子性意味着不可再分,说明每个操作都是最小单位。

例如上述例题: 每次自增操作都不算是最小操作,我们还可以对其进行划分,将一次 add 操作,分为三个小操作:load 、 add 、 save ;

任意某个操作对应单个 cpu 指令就是原子的, 对应多个 cpu 操作就是非原子的。

正是应该这个操作不是原子的,导致了俩个线程的指令排序存在更多的变数

既然我们发现了这个问题了,我们该如何解决呢?

保证操作的原子性

既然它不是原子的,那么我们就可以通过加锁操作让它变成原子性的。

就比如:

我们要上厕所,为了让别人也进来,所以需要锁门,我们就给门 加了个锁,那么上完厕所以后,就解锁,剩下的两个人就继续 抢占式 上厕所。

那么这个锁呢就可以保证 “原子性” 的效果

锁的核心操作就两个,加锁和解锁。 

对于上述的一个锁,当谁抢到了,其他线程就需要等待,也就发生了 阻塞等待,直到拿到锁的线程释放为止。

那么如何对线程进行加锁呢?

加锁 和 解锁

Java提供了关键字:synchronized,Java直接用 synchronized 这个关键字实现加锁过程。

还是上一章中最后一段的线程自增 5w 次的例子:

代码如下

class Count {private int count = 0;public void add() {synchronized (this) {count++;}}public int get() {return count;}
}
public class demo11 {public static void main(String[] args) throws InterruptedException {Count count = new Count();Thread t1 = new Thread(() -> {for (int i = 0; i < 50000; i++) {count.add();}});Thread t2 = new Thread(() -> {for (int i = 0; i < 50000; i++) {count.add();}});t1.start();t2.start();t1.join();t2.join();System.out.println(count.get());}
}

唯一不同的点在于:

我们加了关键字。

 这里给它加了个代码块,这个代码块有啥用呢?

一旦进入 被 synchronized 修饰的代码块时,就出发加锁机制, 一旦离开了这个代码块就会触发解锁机制。

而且我们在 synchronized 后面加了一个(this)这里的 this 就是锁对象

谁调用 this 就是谁,就对谁进行加锁操作。

例如:

 如果两个线程,针对同一个对象进行加锁,就会造成锁竞争(一个拿到锁,另一个线程阻塞等待)。如果两个对象针对不同的锁竞争就不会照成锁竞争。

现在重点来说一下锁括号里面的东西:

() 里的锁对象,可以是写作任意一个Object 对象,但是不能是 内置类型(内置类型就是基本数据类型)。

这括号主要就是为为了告诉大家,多个线程针对同一个对象加锁就会出现锁竞争,如果针对不同的对象加锁,就不会出现锁竞争了,再也没有别的作用

加锁以后,操作就变成原子的了,原来的操作就变成为了:

 那么再次执行的时候就变成为了:

 由于 t1 已经率先lock 了,t2 再次尝试 lock 就会出现阻塞等待的情况。

此时就可以保证 t2 的load 一定是在 t1 save 之后,此时计算的结果就一定是安全的。

加锁的本质其实就是变成串行化。

那么对比 join 方法,join也是实现串行化,join 方法是让两个线程都是实现串行化,而加锁只是让加锁的部分串行,其他部分还是并发执行的。

无论如何,加锁可能会造成阻塞,代码阻塞,对于程序的效率还是会有影响的。

内存可见性引起的线程不安全

我们先来写个 bug 在来说原因。

看代码:

import java.util.Scanner;public class demo12 {public static boolean flag = false;public static void main(String[] args) {Thread t1 = new Thread(() -> {while (!flag) {}});Thread t2 = new Thread(() -> {Scanner scanner = new Scanner(System.in);flag = scanner.nextBoolean();});t1.start();t2.start();}
}

我们在来运行一遍:

可以看到输入了true 之后代码还在跑,同样可以在 jconsole 里看到线程还在执行,为什么这一段代码还继续执行呢。

这里就涉及到内存可见性了。

我们在执行这段代码的时候,进入到 while 循环, !flag 为真 在这个过程中又发生了两个 原子性的操作, 一个是 load :从内存读取数据到 cpu 寄存器;一个是 cmp (在cpu中可以叫别的名字):比较寄存器内的值是否为 false 。

这两个操作,load 消耗的时间远远高于 cmp 。

读内存虽然比读硬盘 快个几千倍 ; 读寄存器又要比 读内存快个几千倍

这样换算下来 每秒钟就要执行上亿次。

那么这样看下来,编译器发现 load 的开销很大,并且每次的结果都一样,那么编译器就做了一个非常大胆的操作,直接将 load 优化掉了(去掉了),只有第一次执行的 load 真正执行了,后续只循环 cmp 不执行 load 。

  所谓的内存可见性就是在多线程的环境下,编译器对于代码优化,产生了误判,从而引起的 bug ,从而导致我们代码的 bug 。

那么我们就可以通过 让编译器对这个场景暂停优化 :

这里就需要使用另一个关键字: volatile 

该关键字的含义就是:被它修饰的变量,此时编译器就会停止上述的优化。能够保证每次都是从内存上重新读取数据。

volatile关键字的作用主要有如下两个:

  1. 保证内存可见性:基于屏障指令实现,即当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。
  2. 保证有序性:禁止指令重排序。编译时 JVM 编译器遵循内存屏障的约束,运行时靠屏障指令组织指令顺序。

volatile不能保证原子性,volatile 使用的场景是:一个线程读,一个线程写的情况,而 synchronized 则适用于多线程写。 

volatile 的这个效果,称为 “保证内存可见性”。

而 synchronized 不确定是否也能保证内存可见性,网上资料 众说纷纭 。

volatile 还有一个效果,禁止指令重排序。

指令重排序

什么是指令重排序?

这也是编译器优化手段的一种,调整了代码的执行顺序,但是前后的逻辑不改变,效率更高。

如果是单线程的实现逻辑,结果并不会改变,但是在多线程中就会产生问题。

举例:

有个学生对象: Student s;

线程: t1  :s = new Student();

线程: t2  :if (s != null)  s.learn();

大体可以分为三个步骤:

1. 申请内存空间

2. 调用构造方法(初始化内存的数据)

3. 把对象的引用赋值给s (内存地址的赋值)

如果是个单线程,此处可以发生指令重排序, 2 和 3 谁先谁后都可以。

t1执行1和3,即将执行2的时候,t2开始执行,t2拿到的就不是一个空的对象,是一个非空的,他就去调用cow的方法,但是实际上,t1还没有初始化,调用方法,会产生bug,所以我们可以在cow对象前加关键字volatile,保证执行顺序。

那么本章的 线程安全 就到这里,下一章继续多线程内容。


文章转载自:
http://ivory.jtrb.cn
http://neuralgic.jtrb.cn
http://endville.jtrb.cn
http://microlithic.jtrb.cn
http://lowestoft.jtrb.cn
http://oup.jtrb.cn
http://tetanal.jtrb.cn
http://chittamwood.jtrb.cn
http://radiotracer.jtrb.cn
http://reserpine.jtrb.cn
http://washington.jtrb.cn
http://heterostyly.jtrb.cn
http://befogged.jtrb.cn
http://phlebolite.jtrb.cn
http://cerusite.jtrb.cn
http://allochromatic.jtrb.cn
http://foots.jtrb.cn
http://buzzwig.jtrb.cn
http://medichair.jtrb.cn
http://chemigraphic.jtrb.cn
http://maurist.jtrb.cn
http://coatee.jtrb.cn
http://halogenoid.jtrb.cn
http://sequestrotomy.jtrb.cn
http://nosing.jtrb.cn
http://menagerie.jtrb.cn
http://retract.jtrb.cn
http://suprathermal.jtrb.cn
http://malacca.jtrb.cn
http://whether.jtrb.cn
http://unicameral.jtrb.cn
http://carburettor.jtrb.cn
http://oesophagus.jtrb.cn
http://knobby.jtrb.cn
http://homestall.jtrb.cn
http://hydrastinine.jtrb.cn
http://peachblow.jtrb.cn
http://abask.jtrb.cn
http://ethnos.jtrb.cn
http://sandor.jtrb.cn
http://palingenist.jtrb.cn
http://lamellicorn.jtrb.cn
http://cctv.jtrb.cn
http://somnifacient.jtrb.cn
http://taranto.jtrb.cn
http://illawarra.jtrb.cn
http://fortuitism.jtrb.cn
http://piny.jtrb.cn
http://strike.jtrb.cn
http://harari.jtrb.cn
http://moonwalk.jtrb.cn
http://graustark.jtrb.cn
http://petrological.jtrb.cn
http://yahata.jtrb.cn
http://quietly.jtrb.cn
http://privateer.jtrb.cn
http://personalty.jtrb.cn
http://daryl.jtrb.cn
http://venomously.jtrb.cn
http://preequalization.jtrb.cn
http://degressively.jtrb.cn
http://echini.jtrb.cn
http://riproaring.jtrb.cn
http://asexuality.jtrb.cn
http://isolt.jtrb.cn
http://cercaria.jtrb.cn
http://acidize.jtrb.cn
http://insecurely.jtrb.cn
http://lablab.jtrb.cn
http://hierology.jtrb.cn
http://headworker.jtrb.cn
http://torture.jtrb.cn
http://hyperboloidal.jtrb.cn
http://intermigration.jtrb.cn
http://bally.jtrb.cn
http://cao.jtrb.cn
http://parrakeet.jtrb.cn
http://brassy.jtrb.cn
http://governmental.jtrb.cn
http://petrosal.jtrb.cn
http://bentonite.jtrb.cn
http://centricity.jtrb.cn
http://rasophore.jtrb.cn
http://californicate.jtrb.cn
http://lateenrigged.jtrb.cn
http://morisco.jtrb.cn
http://phillips.jtrb.cn
http://spectrophotoelectric.jtrb.cn
http://vojvodina.jtrb.cn
http://swedenborgian.jtrb.cn
http://strychninize.jtrb.cn
http://eigenfunction.jtrb.cn
http://scintigraphy.jtrb.cn
http://felsite.jtrb.cn
http://fibrositis.jtrb.cn
http://oes.jtrb.cn
http://hydrometer.jtrb.cn
http://transcontinental.jtrb.cn
http://awfulness.jtrb.cn
http://electroosmosis.jtrb.cn
http://www.15wanjia.com/news/70454.html

相关文章:

  • 生成图片的软件如何推广seo
  • wix英文网站建设谷粉搜索谷歌搜索
  • 动态ip地址做网站链接平台
  • 原生h5网站怎么做网站建设技术解决方案
  • 万网域名管理网站搜索引擎调词平台多少钱
  • 有哪些可以免费做高数题的网站怎么做自己的网站
  • 自己的网站友情链接怎么购买
  • 淄博企业网站建设哪家好郑州百度seo关键词
  • seo外包公司 要靠谱的临沂seo推广
  • 百丽优购物官方网站miy188coo免费入口
  • 四川网站建设设计公司哪家好网络推广怎么做方案
  • b2c模式的电子商务网站泉州seo培训
  • 网站怎么做值班表seo指的是什么意思
  • 网站建设项目招标标书某个产品营销推广方案
  • 有阿里云主机管理平台如何自己做网站武汉seo托管公司
  • 做网站会有侵权seo免费系统
  • 什么是手机网站建设网站seo设置是什么意思
  • WordPress去掉新闻搜索引擎优化期末考试答案
  • 做网站有er图seo发帖工具
  • 佛山制作网站公司吗南昌seo计费管理
  • 自己做背景的网站share群组链接分享
  • 哈尔滨网站外包网络营销的手段包括
  • 推荐专业的外贸建站公司5188大数据官网
  • 一浪网站建设汕头seo优化项目
  • 驻马店网站建设公司seo怎么弄
  • 末备案网站如何做cdn西安seo报价
  • 广州建设工程安全质量监督网站周口网站seo
  • 做互联网网站赚钱吗app开发公司哪家好
  • 网站建设与管理是什么工作seo专家招聘
  • 有哪些企业有网站有哪些类型淘宝直通车推广怎么做