volatile非原子性的示例

本文通过一个Java多线程示例展示了volatile关键字并不能保证操作的原子性。当多个线程同时对共享变量进行递增操作时,volatile无法解决线程安全问题,导致最终结果不准确。

volatile非原子性的示例

package com.stono.thread2.page124;

public class MyThread extends Thread {

    volatile public static int count;
    private static void addCount() {
        for(int i=0;i<100;i++) {
            count++;
        }
        System.out.println("count = "+count);
    }
    
    @Override
    public void run() {
        addCount();
    }
}
package com.stono.thread2.page124;

public class Run {

    public static void main(String[] args) {
        MyThread [] myThreads = new MyThread[100];
        for(int i=0;i<100;i++) {
            myThreads[i] = new MyThread();
        }
        for(int i=0;i<100;i++) {
            myThreads[i].start();
        }
    }

}

对于count变量,存在非线程安全的问题,多个线程同时对count进行++操作,最后导致count的结果不是10000;

示例来源于《Java多线程编程核心技术》- 高洪岩著 Page 124

 

转载于:https://www.cnblogs.com/stono/p/8442109.html

`volatile` 不能保证原子性原子性是指一个操作是不可中断的、不可分割的,要么整个操作完成,要么没有完成。`volatile` 主要解决可见性的问题,通过强制将当前线程修改后的值写回内存并使得其他线程中该值无效的方式保证其可见性,通过禁止指令重排的方式保证有序性,但它不是锁,没做任何可以保证原子性的处理,所以不能保证原子性[^2][^4][^5]。 而 `synchronized` 可以保证原子性,因为被 `synchronized` 修饰的代码片段,在进入之前加了锁,只要它没执行完,其他线程是无法获得锁执行这段代码片段的,就可以保证它内部的代码可以全部被执行,进而保证原子性[^4]。 例如以下代码示例: ```java public class VolatileAtomicityExample { // 使用 volatile 修饰变量 public static volatile int counter = 0; public static void main(String[] args) throws InterruptedException { // 创建两个线程 Thread thread1 = new Thread(() -> { for (int i = 0; i < 1000; i++) { counter++; } }); Thread thread2 = new Thread(() -> { for (int i = 0; i < 1000; i++) { counter++; } }); // 启动线程 thread1.start(); thread2.start(); // 等待两个线程执行完毕 thread1.join(); thread2.join(); // 输出结果 System.out.println("Counter value: " + counter); } } ``` 在上述代码中,`counter` 变量使用 `volatile` 修饰,按预期两个线程各执行 1000 次自增操作后,`counter` 的值应该是 2000,但由于 `volatile` 不能保证原子性,`counter++` 这个操作不是原子操作,它包含读取、加 1、写入三个步骤,多个线程可能同时读取到相同的值,然后进行加 1 操作,最后写入相同的值,导致最终结果可能小于 2000。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值