原子访问

原子操作要么不发生,要么全部发生。

下面是原子的:

(1)读写基本类型数据(long和double除外)

(2)volatile修饰的变量(包含long和double)读写原子


原子动作不能重叠,不用担心线程干扰了,但是这不意味着就不用同步了,因为内存一致性的错误还是可能的。

使用volatile变量减少了内存一致性错误的风险,因为任何写volatile变量建立一个happen-before原则给 后面读同一个变量的操作。这就意味着,改变一个volatile变量对其他

线程总是可见的。更多的,当一个线程读一个volatile变量,他看到的不仅仅是volatile最新的改变,还包含导致这个变化的代码的副作用(??


使用原子变量访问比synchronized代码更高效,但是要求程序员更加关心内存一致性问题。是否值得额外的努力取决于程序的大小和复杂程度。


下面这个应该是没有处理内存一致性,所以结果不会是100*10000,加上volatile反而不如不加得到的结果大。

public class VolatileTest {
    public static volatile  int count=0;
    
    public static void increase(){
        count++;
    }
    private static final int THREADS_COUNT = 100;
    public static void main(String[] args) {
        Thread[] threads = new Thread[THREADS_COUNT];
        for(int i =0; i< THREADS_COUNT; i++){
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int i=0; i < 10000; i++){
                        increase();
                    }
                }
            });
            threads[i].start();
        }
        while(Thread.activeCount() > 1){
            Thread.yield();
        }
        System.out.println(count);
    }
}

使用volatile虽然保证了可见性,但是内存一致性还是要解决。

不符合下面的规则也是要同步保证原子性:

(1)运算结果不依赖变量当前值(++操作显然不符合),或者能够确保只有一个线程修改变量的值

(2)变量不需要与其他状态变量共同参与不变约束(这个不太理解啊?)


根据第一天,volatile变量作为线程之间公共属性貌似可以,不过要谨慎处理。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值