Volatile关键字

Volatile 关键字的作用是变量在多个线程之间可见。

class ThreadVolatileDemo extends Thread {
public boolean flag = true;
@Override
public void run() {
System.out.println(“开始执行子线程….”);
while (flag) {
}
System.out.println(“线程停止”);
}
public void setRuning(boolean flag) {
this.flag = flag;
}

}

public class ThreadVolatile {
public static void main(String[] args) throws InterruptedException {
ThreadVolatileDemo threadVolatileDemo = new ThreadVolatileDemo();
threadVolatileDemo.start();
Thread.sleep(3000);
threadVolatileDemo.setRuning(false);
System.out.println(“flag 已经设置成false”);
Thread.sleep(1000);
System.out.println(threadVolatileDemo.flag);

}

}

运行结果:开始执行子线程。。

已经将结果设置为fasle为什么?还一直在运行呢。
原因:线程之间是不可见的,读取的是副本,没有及时读取到主内存结果。
“主内存”中取值解决办法使用Volatile关键字将解决线程之间可见性, 强制线程每次读取该值的时候都去主内存读取。

Volatile非原子性
注意: Volatile非原子性
public class VolatileNoAtomic extends Thread {
private static volatile int count;

// private static AtomicInteger count = new AtomicInteger(0);
private static void addCount() {
    for (int i = 0; i < 1000; i++) {
        count++;
        // count.incrementAndGet();
    }
    System.out.println(count);
}

public void run() {
    addCount();
}

public static void main(String[] args) {

    VolatileNoAtomic[] arr = new VolatileNoAtomic[100];
    for (int i = 0; i < 10; i++) {
        arr[i] = new VolatileNoAtomic();
    }

    for (int i = 0; i < 10; i++) {
        arr[i].start();
    }
}

}

结果发现 数据不同步,因为Volatile不用具备原子性。

使用AtomicInteger原子类
AtomicInteger是一个提供原子操作的Integer类,通过线程安全的方式操作加减。
public class VolatileNoAtomic extends Thread {
static int count = 0;
private static AtomicInteger atomicInteger = new AtomicInteger(0);

@Override
public void run() {
    for (int i = 0; i < 1000; i++) {
        //等同于i++
        atomicInteger.incrementAndGet();
    }
    System.out.println(count);
}

public static void main(String[] args) {
    // 初始化10个线程
    VolatileNoAtomic[] volatileNoAtomic = new VolatileNoAtomic[10];
    for (int i = 0; i < 10; i++) {
        // 创建
        volatileNoAtomic[i] = new VolatileNoAtomic();
    }
    for (int i = 0; i < volatileNoAtomic.length; i++) {
        volatileNoAtomic[i].start();
    }
}

}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 591235401@qq.com

文章标题:Volatile关键字

本文作者:阿杜同学

发布时间:2019-01-05, 20:52:21

最后更新:2019-01-05, 20:52:21

原始链接:http://yoursite.com/2019/01/05/Volatile%E5%85%B3%E9%94%AE%E5%AD%97/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录