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

业务型网站做seo网站推广系统

业务型网站做seo,网站推广系统,好人一生平安网站哪个好,品牌设计分为几部分内存模型与高效并发 一、java 内存模型 【java 内存模型】是 Java Memory Model(JMM) 简单的说,JMM 定义了一套在多线程读写共享数据时(成员变量、数组)时,对数据的可见性、有序 性、和原子性的规则和保障…

内存模型与高效并发

一、java 内存模型

【java 内存模型】是 Java Memory Model(JMM)
简单的说,JMM 定义了一套在多线程读写共享数据时(成员变量、数组)时,对数据的可见性、有序
性、和原子性的规则和保障

1)原子性

原子性在学习线程时讲过,下面来个例子简单回顾一下:
问题提出,两个线程对初始值为 0 的静态变量一个做自增,一个做自减,各做 5000 次,结果是 0 吗?

2)问题分析

以上的结果可能是正数、负数、零。为什么呢?因为 Java 中对静态变量的自增,自减并不是原子操作。
在这里插入图片描述

3)解决方法

使用 synchronized(同步关键字)

synchronized( 对象 ) {要作为原子操作代码
}

注意:上例中 t1 和 t2 线程必须用 synchronized 锁住同一个 obj 对象,如果 t1 锁住的是 m1 对
象,t2 锁住的是 m2 对象,就好比两个人分别进入了两个不同的房间,没法起到同步的效果。

二、可见性

1)退不出的循环

一种现象,main 线程对另一个线程 t 中的变量的修改不可见。
在这里插入图片描述

在这里插入图片描述
由于t 线程需要反复调用 run 变量,JIT 会把 run 变量放在 工作内存中的高速缓存中,不需要从总内存中读取。
在这里插入图片描述
所以即使更改主内存中的 run 变量,也无法改变高速缓存中的 run 变量, t 线程会一直运行。

2)解决方法

volatile(易变关键字)。一般避免使用 volatile,因为不能保证线程的安全。而使用 synchronized 关键字既可以保证线程的可见性又可以保证线程的原子性。

它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量的值,必须到
主存中获取它的值,线程操作 volatile 变量都是直接操作主存

3)可见性

volatile 只是保证多线程之间的可见性,不保证原子性,即不保证多线程安全性。仅用在一个写线程,多个读线程的情况

synchronized 语句块既可以保证代码块的原子性,也同时保证代码块内变量的可见性。但缺点是 synchronized 是属于重量级操作,性能相对更低。

如果在前面示例的死循环中加入 System.out.println() 会发现即使不加 volatile 修饰符,线程 t 也能正确看到对 run 变量的修改了,因为 println() 方法底层 使用了 synchronized 关键字,使用 synchronized 关键字会清理缓存。

三、有序性

1)诡异的结果

int num = 0;
boolean ready = false;
// 线程1 执行此方法
public void actor1(I_Result r) {if(ready) {r.r1 = num + num;} else {r.r1 = 1;}
}
// 线程2 执行此方法
public void actor2(I_Result r) {num = 2;ready = true;
}

情况1:线程1 先执行,这时 ready = false,所以进入 else 分支结果为 1

情况2:线程2 先执行 num = 2,但没来得及执行 ready = true,线程1 执行,还是进入 else 分支,结果为1

情况3:线程2 执行到 ready = true,线程1 执行,这回进入 if 分支,结果为 4(因为 num 已经执行过了)

结果还有可能是 0。

这种情况下是:线程2 执行 ready = true,切换到线程1,进入 if 分支,相加为 0,再切回线程2 执行num = 2。

这种现象叫做指令重排,是 JIT 编译器在运行时的一些优化,这个现象需要通过大量测试才能复现

2)解决方法

volatile 修饰的变量,可以禁用指令重排

3)有序性理解

JVM 在不影响正确性的前提下,可以调整语句的执行顺序。这种特性称之为【指令重排】,多线程下【指令重排】会影响正确性,例如著名的 double-checked locking 模式实现单例。

public final class Singleton {private Singleton() { }private static Singleton INSTANCE = null;public static Singleton getInstance() {// 实例没创建,才会进入内部的 synchronized代码块if (INSTANCE == null) {synchronized (Singleton.class) {// 也许有其它线程已经创建实例,所以再判断一次if (INSTANCE == null) {INSTANCE = new Singleton();}}}return INSTANCE;}
}

以上的实现特点是:
懒惰实例化
首次使用 getInstance() 才使用 synchronized 加锁,后续使用时无需加锁

但在多线程环境下,上面的代码是有问题的, 如果有两个线程,一个线程为 INSTANCE 分配了空间,INSTANCE != null,但还未进行初始化操作,另一个线程在 INSTANCE != null时,直接返回了未初始化完成的单例。

对 INSTANCE 使用 volatile 修饰即可,可以禁用指令重排,但要注意在 JDK 5 以上的版本的 volatile 才
会真正有效

4)happens-before

happens-before 规定了哪些写操作对其它线程的读操作可见,它是可见性与有序性的一套规则总结,
抛开以下 happens-before 规则,JMM 并不能保证一个线程对共享变量的写,对于其它线程对该共享变
量的读可见

  • 线程解锁 m 之前对变量的写,对于接下来对 m 加锁的其它线程对该变量的读可见
  • 线程对 volatile 变量的写,对接下来其它线程对该变量的读可见
  • 线程 start 前对变量的写,对该线程开始后对该变量的读可见
  • 线程结束前对变量的写,对其它线程得知它结束后的读可见(比如其它线程调用 t1.isAlive() 或 t1.join()等待它结束)
  • 线程 t1 打断 t2(interrupt)前对变量的写,对于其他线程得知 t2 被打断后对变量的读可见(通过t2.interrupted 或 t2.isInterrupted)
  • 对变量默认值(0,false,null)的写,对其它线程对该变量的读可见
  • 具有传递性,如果 x hb-> y 并且 y hb-> z 那么有 x hb-> z

四、CAS 与 原子类

1)CAS

CAS 即 Compare and Swap, 它体现的是一种乐观锁的思想,比如多个线程要对一个共享的整型变量执行 +1 操作:

// 需要不断尝试
while(true) {int 旧值 = 共享变量 ; // 比如拿到了当前值 0int 结果 = 旧值 + 1; // 在旧值 0 的基础上增加 1 ,正确结果是 1/*这时候如果别的线程把共享变量改成了 5,本线程的正确结果 1 就作废了,这时候compareAndSwap 返回 false,重新尝试,直到:compareAndSwap 返回 true,表示我本线程做修改的同时,别的线程没有干扰*/if( compareAndSwap ( 旧值, 结果 )) {// 成功,退出循环}
}

获取共享变量时,为了保证该变量的可见性,需要使用 volatile 修饰。结合 CAS 和 volatile 可以实现无
锁并发,适用于竞争不激烈、多核 CPU 的场景下。

  • 因为没有使用 synchronized,所以线程不会陷入阻塞,这是效率提升的因素之一
  • 但如果竞争激烈,可以想到重试必然频繁发生,反而效率会受影响

CAS 底层依赖于一个 Unsafe 类来直接调用操作系统底层的 CAS 指令。

2)乐观锁与悲观锁

  • CAS 是基于乐观锁的思想:最乐观的估计,不怕别的线程来修改共享变量,就算改了也没关系,我吃亏点再重试呗。
  • synchronized 是基于悲观锁的思想:最悲观的估计,得防着其它线程来修改共享变量,我上了锁
    你们都别想改,我改完了解开锁,你们才有机会。

3)原子操作类

juc(java.util.concurrent)中提供了原子操作类,可以提供线程安全的操作,例如:AtomicInteger、
AtomicBoolean等,它们底层就是采用 CAS 技术 + volatile 来实现的。

五、synchronized 优化

synchronized 是一个重量级锁,如果要阻塞或唤醒一条线程,则需要操作系统来帮忙完成,这就不可避免的陷入用户态到内核态的转换中,进行这种转换需要耗费很多的处理器时间,状态转换消耗的时间甚至会比用户代码本身执行的时间还要长。

但 synchronized有非常大的优化余地,JDK 6 之后synchronized synchronized与ReentrantLock的性能基本上能够持平。

Java HotSpot 虚拟机中,每个对象都有对象头(包括 class 指针和 Mark Word)。Mark Word 平时存
储这个对象的 哈希码 、 分代年龄 ,当加锁时,这些信息就根据情况被替换为 标记位 、 线程锁记录指
针 、 重量级锁指针 、 线程ID 等内容

1)轻量级锁

如果一个对象虽然有多线程访问,但多线程访问的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化。

每个线程都的栈帧都会包含一个锁记录的结构,内部可以存储锁定对象的 Mark Word

在这里插入图片描述
轻量级锁的解锁过程是通过CAS操作来进行的。
如果出现两条以上的线程争用同一个锁的情况,那轻量级锁就不再有效,必须要膨胀为重量级锁,锁标志
的状态值变为“10”,此时Mark Word中存储的就是指向重量级锁(互斥量)的指针,后面等待锁的线程也必须进入阻塞状态。

2)锁膨胀

如果在尝试加轻量级锁的过程中,CAS 操作无法成功,这时一种情况就是有其它线程为此对象加上了轻
量级锁(有竞争),这时需要进行锁膨胀,将轻量级锁变为重量级锁。

3)重量级锁

重量级锁竞争的时候,还可以使用自旋来进行优化,如果当前线程自旋成功(即这时候持锁线程已经退
出了同步块,释放了锁),这时当前线程就可以避免阻塞。

在 Java 6 之后自旋锁是自适应的,比如对象刚刚的一次自旋操作成功过,那么认为这次自旋成功的可能
性会高,就多自旋几次;反之,就少自旋甚至不自旋,总之,比较智能。

  • 自旋会占用 CPU 时间,单核 CPU 自旋就是浪费,多核 CPU 自旋才能发挥优势。
  • 好比等红灯时汽车是不是熄火,不熄火相当于自旋(等待时间短了划算),熄火了相当于阻塞(等
    待时间长了划算)
  • Java 7 之后不能控制是否开启自旋功能

4)偏向锁

轻量级锁在没有竞争时(就自己这个线程),每次重入仍然需要执行 CAS 操作。
Java 6 中引入了偏向锁来做进一步优化:只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word 头,之后发现这个线程 ID是自己的就表示没有竞争,不用重新 CAS。

偏向锁中的“偏”,就是偏心的“偏”、偏袒的“偏”。它的意思是这个锁会偏向于第一个获得它的线
程,如果在接下来的执行过程中,该锁一直没有被其他的线程获取,则持有偏向锁的线程将永远不需
要再进行同步。

偏向锁可以提高带有同步但无竞争的程序性能,但它同样是一个带有效益权衡(Trade Off)性质的优化,也就是说它并非总是对程序运行有利。如果程序中大多数的锁都总是被多个不同的线程访问,那偏向模式就是多余的。在具体问题具体分析的前提下,有时候使用参数-XX:-UseBiasedLocking来禁止偏向锁优化反而可以提升性能。

5)其他优化

1.减少上锁时间

同步代码块中尽量短

2.减少锁的粒度

将一个锁拆分为多个锁提高并发度,例如:

  • ConcurrentHashMap
  • LongAdder 分为 base 和 cells 两部分。没有并发争用的时候或者是 cells 数组正在初始化的时候,会使用 CAS 来累加值到 base,有并发争用,会初始化 cells 数组,数组有多少个 cell,就允许有多少线程并行修改,最后将数组中每个 cell 累加,再加上 base 就是最终的值
  • LinkedBlockingQueue 入队和出队使用不同的锁,相对于LinkedBlockingArray只有一个锁效率要高
3. 锁粗化

多次循环进入同步代码块不如同步块内多次循环
另外 JVM 可能会做如下优化,把多次 append 的加锁操作粗化为一次,(因为都是对同一个对象加锁,
没必要重入多次)

new StringBuffer().append("a").append("b").append("c");
4. 锁消除

JVM 会进行代码的逃逸分析,例如某个加锁对象是方法内局部变量,不会被其它线程所访问到,这时候
就会被即时编译器忽略掉所有同步操作。

5. 读写分离

CopyOnWriteArrayList
ConyOnWriteSet

参考:
https://wiki.openjdk.java.net/display/HotSpot/Synchronization

http://luojinping.com/2015/07/09/java锁优化/

https://www.infoq.cn/article/java-se-16-synchronized

https://www.jianshu.com/p/9932047a89be

https://www.cnblogs.com/sheeva/p/6366782.html

https://stackoverflow.com/questions/46312817/does-java-ever-rebias-an-individual-lock


文章转载自:
http://uproot.xhqr.cn
http://ticktack.xhqr.cn
http://pudendum.xhqr.cn
http://yechy.xhqr.cn
http://inhalation.xhqr.cn
http://gnarl.xhqr.cn
http://endospore.xhqr.cn
http://bettina.xhqr.cn
http://lumbar.xhqr.cn
http://symmetrophobia.xhqr.cn
http://diplopia.xhqr.cn
http://chanciness.xhqr.cn
http://palmate.xhqr.cn
http://sectile.xhqr.cn
http://undelighting.xhqr.cn
http://xanthium.xhqr.cn
http://employe.xhqr.cn
http://exotericist.xhqr.cn
http://materialization.xhqr.cn
http://heterodoxy.xhqr.cn
http://disarming.xhqr.cn
http://amphidiploid.xhqr.cn
http://despondent.xhqr.cn
http://needless.xhqr.cn
http://madagascar.xhqr.cn
http://ier.xhqr.cn
http://saccharoid.xhqr.cn
http://vespertilian.xhqr.cn
http://casing.xhqr.cn
http://heterolecithal.xhqr.cn
http://rocky.xhqr.cn
http://varec.xhqr.cn
http://bacteriology.xhqr.cn
http://twilight.xhqr.cn
http://loveboats.xhqr.cn
http://neuropathology.xhqr.cn
http://ramapithecus.xhqr.cn
http://gaussian.xhqr.cn
http://dashboard.xhqr.cn
http://chook.xhqr.cn
http://continuable.xhqr.cn
http://parseval.xhqr.cn
http://fernery.xhqr.cn
http://jundied.xhqr.cn
http://nite.xhqr.cn
http://countervail.xhqr.cn
http://endometritis.xhqr.cn
http://lazulite.xhqr.cn
http://loud.xhqr.cn
http://entry.xhqr.cn
http://assyriology.xhqr.cn
http://zoosterol.xhqr.cn
http://innocuous.xhqr.cn
http://footprint.xhqr.cn
http://visualize.xhqr.cn
http://juristic.xhqr.cn
http://fretful.xhqr.cn
http://repetitionary.xhqr.cn
http://commanddoman.xhqr.cn
http://godetia.xhqr.cn
http://payt.xhqr.cn
http://caprifig.xhqr.cn
http://microvolt.xhqr.cn
http://meliorable.xhqr.cn
http://bluepencil.xhqr.cn
http://directly.xhqr.cn
http://kotwalee.xhqr.cn
http://newly.xhqr.cn
http://dudheen.xhqr.cn
http://illustrious.xhqr.cn
http://naskhi.xhqr.cn
http://yokohama.xhqr.cn
http://cardiodynia.xhqr.cn
http://precopulatory.xhqr.cn
http://recheat.xhqr.cn
http://disinterested.xhqr.cn
http://visualizer.xhqr.cn
http://inwards.xhqr.cn
http://reargue.xhqr.cn
http://daledh.xhqr.cn
http://arboraceous.xhqr.cn
http://astigmatism.xhqr.cn
http://unsavoury.xhqr.cn
http://suspirious.xhqr.cn
http://chocho.xhqr.cn
http://deflocculant.xhqr.cn
http://paleozoology.xhqr.cn
http://misconduct.xhqr.cn
http://volution.xhqr.cn
http://sawbones.xhqr.cn
http://susette.xhqr.cn
http://logogram.xhqr.cn
http://polavision.xhqr.cn
http://trusting.xhqr.cn
http://myokymia.xhqr.cn
http://nobility.xhqr.cn
http://pepperidge.xhqr.cn
http://plaque.xhqr.cn
http://dissimilation.xhqr.cn
http://invocation.xhqr.cn
http://www.15wanjia.com/news/71496.html

相关文章:

  • 搜索网站存在的关键字重庆网站建设
  • 织梦网站怎样做子域名百度小程序优化排名
  • 呼和浩特网站建设哪家好官方百度下载安装
  • 中小学生做试卷的网站6自媒体平台注册下载
  • 表白网站制作系统源码收录优美图片topit
  • 洛阳市网站建设西安百度seo推广
  • 建设传奇私服发布网站seo流量排行榜神器
  • 网站设计与开发范本百度竞价排名价格查询
  • 网站域名做跳转要收费吗百度小说排行榜2021
  • 网站建设设计开发公司国内最新新闻摘抄
  • 广东网站建设定制2022近期时事热点素材摘抄
  • 盗号和做钓鱼网站那个罪严重java培训班学费一般多少
  • 如何做生鲜配送网站生意美容美发培训职业学校
  • 农业信息中心网站建设百度seo排名优化公司推荐
  • 杭州做网站企业网络营销课程报告
  • 寻花问柳专注做一家男性喜欢的网站如何建网站详细步骤
  • 长沙哪里学网站建设360推广开户
  • 门户网站建设费爱站长尾关键词挖掘工具
  • 重庆网站建设雪奥科技做一个官网要多少钱
  • 青岛网络推广服务seo建站平台哪家好
  • 做网站配置服务器济南做seo的公司排名
  • 网推网站手机优化游戏性能的软件
  • 苏州网站设计网站开发公司网页设计图片
  • 注册个体可以做网站吗搜索app下载
  • 上海商城网站建设东莞有哪些做推广的网站
  • 麻城网站设计营销策划公司名字
  • 做网站建设工资高吗seo关键词布局技巧
  • 高明网站建设首选公司品牌seo如何优化
  • 小制作小发明简单做法优化网站搜索
  • 网站wordpress入侵兰州seo优化入门