java多线程-3-volatile

2019-09-30  本文已影响0人  宠辱不惊的咸鱼

缓存一致性问题

并发性质

// 线程1 - 负责加载context,然后发通知
context = loadContext(); // 语句1
inited = true;           // 语句2

//线程2 - 监听inited通知信号,业务处理
while(!inited) {
    sleep();
}
doSomethingWithConfig(context);

JMM Java内存模型

实现机制

举例场景

// 只有volatile
public class Test {
    private volatile int inc = 0;
    public void increase() {
        inc++; // 线程1和2同时读入inc,线程2快速+1写回主内存;由于线程1已读过值,直接开加,所以错了
    }
    public static void main(String[] args) {
        final Test test = new Test();
        for(int i = 0; i < 10; i++) {
            new Thread(() -> {
                for(int j = 0; j < 1000; j++) {
                    test.increase();
                }
            }).start();
        }
        while(Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println(test.inc);
    }
}

// synchronized,阻塞了从主内存取值的动作
private int inc = 0;
public synchronized void increase() {
    inc++;
}

// Lock
private int inc = 0;
Lock lock = new ReentrantLock();
public void increase() {
    try {
        lock.lock();
        inc++;
    } finally {
        lock.unlock();
    }
}

// AtomicInteger
private AtomicInteger inc = new AtomicInteger();
public void increase() {
    inc.getAndIncrement();
}

public final int getAndIncrement() {
    return unsafe.getAndAddInt(this, valueOffset, 1);
}

public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

    return var5;
}
上一篇 下一篇

猜你喜欢

热点阅读