并发编程中的三个问题有哪些 并发编程的三大问题(2)
并发编程中的三个问题有哪些
思考:最终number结果可能是多少?
结果可能是5000,也可能是小于5000的结果都有可能
对于 number++ 而言(number 为静态变量),实际会产生如下的 JVM 字节码指令:
9: getstatic #12 // Field number:I
12: iconst_1
13: iadd
14: putstatic #12 // Field number:I
可见number++是由多条语句组成,以上多条指令在一个线程的情况下是不会出问题的,但是在多线程情况下就可能会出现问题。比如一个线程在执行13: iadd时,另一个线程又执行9: getstatic。会导致两次number++,实际上只加了1。
总结:并发编程时,会出现原子性问题,当一个线程对共享变量操作到一半时,另外的线程也有可能来操作共享变量,干扰了前一个线程的操作。
3.有序性
有序性(Ordering):是指程序中代码的执行顺序,Java在编译时和运行时会对代码进行优化,会导致程序最终的执行顺序不一定就是我们编写代码时的顺序
3.1. 有序性可见性案例演示
有序性使用jcstress是java并发压测工具
pom文件,添加依赖
<dependency>
<groupId>org.openjdk.jcstress</groupId>
<artifactId>jcstress-core</artifactId>
<version>0.5</version>
</dependency>
代码
@JCStressTest
@Outcome(id = {"1", "4"}, expect = Expect.ACCEPTABLE, desc = "ok")
@Outcome(id = "0", expect = Expect.ACCEPTABLE_INTERESTING, desc = "danger")
@State
public class OrderingTest {
int num = 0;
boolean ready = false;
// 线程1执行的代码
@Actor
public void actor1(I_Result r) {
if (ready) {
r.r1 = num + num;
} else {
r.r1 = 1;
}
}
// 线程2执行的代码
@Actor
public void actor2(I_Result r) {
num = 2;
ready = true;
}
}
I_Result 是一个对象,有一个属性 r1 用来保存结果思考:在多线程情况下可能出现几种结果?
- 情况1:线程1先执行actor1,这时ready = false,所以进入else分支结果为1。
- 情况2:线程2执行到actor2,执行了num = 2;和ready = true,线程1执行,这回进入 if 分支,结果为 4。
- 情况3:线程2先执行actor2,只执行num = 2;但没来得及执行 ready = true,线程1执行,还是进入else分支,结果为1。
注意:还有第四种情况
种结果0
- 情况4:线程2java编译后结果
ready = true;
num = 2;
线程2先执行actor2,执行了ready = true,但没来得及执行执行num = 2,线程1执行,还是进入if分支,结果为0
相关阅读
-
深入解析:MySQL常用优化技巧及方法
正文核心导读:的内容,具体内容如下: 在数据库管理和应用开发中,性能优化是一个重要的环节。 特别是在处理大量数据和复杂查询时,一个优化得当的MySQL数据库可以大大提高应用程序的
-
OSI七层网络模型物理层详解 物理层的主要功能和特点有哪些
下面为网友们详细介绍OSI七层网络模型物理层详解的相关话题,接下来一起来看看吧。 物理层是OSI模型中的第一层,它负责在物理媒介上传输原始比特流,并定义了传输介质、传输速率、编码
-
lol国服查询实时排名网站 英雄联盟排行榜查询方法
文章导读:lol国服查询实时排名网站和英雄联盟排行榜查询方法的相关知识,接下来一起来看看吧。 在英雄联盟手游中玩家们进行排位赛以后是有评分和排名的,不过对于新手玩家们来说可能
-
mysql:replica_skip_errors参数配置推荐
IT袋网网为大家说一说mysql的介绍,相关内容具体如下: MySQL的 replica_skip_errors 参数允许用户指定要在复制过程中跳过的错误类型。 当出现指定错误时,从服务器不会停止复制,而是跳过错误继


