当前位置:网站首页>JUC (5): Problems caused by sharing
JUC (5): Problems caused by sharing
2022-07-30 02:53:00 【Working boy~】
Java代码示例
两个线程对初始值为 0 的静态变量一个做自增,一个做自减,各做 5000 次,结果是 0 吗?
static int counter = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
counter++;
}
}, "t1");
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
counter--;
}
}, "t2");
t1.start();
t2.start();
t1.join();
t2.join();
log.debug("{}",counter);
}
问题分析
以上的结果可能是正数、负数、零.为什么呢?因为 Java 中对静态变量的自增,自减并不是原子操作,要彻底理解,必须从字节码来进行分析
例如对于 i++ 而言(i 为静态变量),实际会产生如下的 JVM 字节码指令:
getstatic i // 获取静态变量i的值
iconst_1 // 准备常量1
iadd // 自增
putstatic i // 将修改后的值存入静态变量i
而对应 i-- 也是类似:
getstatic i // 获取静态变量i的值
iconst_1 // 准备常量1
isub // 自减
putstatic i // 将修改后的值存入静态变量i
而 Java 的内存模型如下,完成静态变量的自增,自减需要在主存和工作内存中进行数据交换:
如果是单线程以上 8 行代码是顺序执行(不会交错)没有问题:
但多线程下这 8 行代码可能交错运行: 出现负数的情况:
出现正数的情况:
临界区 Critical Section
一个程序运行多个线程本身是没有问题的
问题出在多个线程访问共享资源
多个线程读共享资源其实也没有问题
在多个线程对共享资源读写操作时发生指令交错,就会出现问题
一段代码块内如果存在对共享资源的多线程读写操作,称这段代码块为临界区
static int counter = 0;
static void increment()
// 临界区
{
counter++;
}
static void decrement()
// 临界区
{
counter--;
}
竞态条件 Race Condition
多个线程在临界区内执行,由于代码的执行序列(字节码)不同而导致结果无法预测,称之为发生了竞态条件
边栏推荐
猜你喜欢
随机推荐
ESP8266 +0.96" I2C OLED Dial Clock
新手入门上位机开发 C#语言:PC串口发送数据
【基于RT-Thread+RA6M4的智能鱼缸系统设计之鱼我所欲也】
Oracle 迁移至Mysql
Not enough information to list load addresses in the image map. (STM32 compilation error)
【服务器存储数据恢复】华为OceanStor某型号存储raid5数据恢复案例
FL Studio官方20.9中文版无需汉化补丁,正确安装并设置切换
go grpc custom interceptor
奥比中光高级副总裁王兆民离职 董事会秘书暂未取得资格证
票房破7.9亿美元,最近这部恐龙爽片你看了吗?
开放地址法哈希实现——二次探测法
The relationship between the number of Oracle processes and the number of sessions
DAP数据加工流程梳理
影响小程序开发费用的三个因素!
详解轮播图二-通过left定位来轮播图片
Oracle 进程数和会话数的关系
【C语言刷LeetCode】451. 根据字符出现频率排序(M)
力扣(LeetCode)210. 课程表 II(2022.07.29)
STM32L4R9ZIY6PTR STM32L4 high-performance embedded-MCU
Not enough information to list load addresses in the image map.(STM32编译报错)









