java多线程 操作list_Java多线程 volatile适用的场景:纯赋值的操作

volatile 修饰布尔的标记

volatile 适用于 boolean flag 如果一个共享变量, 一直只被各个线程赋值, 而没有其他的操作, 那么就可以用volatile来代替synchronized 或者代替原子变量, 因为对布尔变量的赋值自身是有原子性的, 而volatile保证了可见性, 就满足了线程安全. 因为布尔值, 只是改成true或者false, 具有原子性, 而不是像 a++操作是非原子性的.

volatile 修饰布尔适用的场景

如下的代码演示了 volatile 适用的场景. 关键是如下的方法setDone,只是直接把done 改成了true, 而没有像a++操作那样, 需要读取a之前的值 . 只是修改布尔值是原子性的. 因此适用.

f6f7238ba676be3290d4c6391d98e3c2.png
package com.thread.jmm;import java.util.concurrent.atomic.AtomicInteger;/** * 类名称:UseVolatileInBoolean * 类描述:volatile 适用于 Boolean变量的并发修改 赋值 * * @author: https://javaweixin6.blog.csdn.net/ * 创建时间:2020/9/6 10:41 * Version 1.0 */public class UseVolatileInBoolean  implements Runnable {    volatile boolean done  = false;    //原子类, 统计执行了多少次    AtomicInteger atomicInteger = new AtomicInteger();    public static void main(String[] args) throws InterruptedException {        UseVolatileInBoolean runnable = new UseVolatileInBoolean();        Thread thread1 = new Thread(runnable);        Thread thread2 = new Thread(runnable);        thread1.start();        thread2.start();        //主线程等待子线程执行完毕        thread1.join();        thread2.join();        System.out.println(runnable.done);        System.out.println("运行次数 : "+runnable.atomicInteger.get());    }    @Override    public void run() {            for (int i = 0; i 

如下图所示的运行结果是为true

48797c1e48f2699a62894fa5833d025a.png

volatile 修饰布尔的标记位不适用的场景

如下的代码演示了volatile 修饰布尔的标记位不适用的场景 . 主要是flipDone方法中, 执行的是done = !done 是要先读取done的值, 再修改, 那么此时就不再是原子性的操作, 就可能会出现并发安全性问题.

package com.thread.jmm;import java.util.concurrent.atomic.AtomicInteger;/** * 类名称:UseVolatileInBoolean * 类描述:volatile 不适用的情况 Boolean * * @author: https://javaweixin6.blog.csdn.net/ * 创建时间:2020/9/6 10:41 * Version 1.0 */public class IncorrentVolatileInBoolean implements Runnable {    volatile boolean done  = false;    //原子类, 统计执行了多少次    AtomicInteger atomicInteger = new AtomicInteger();    public static void main(String[] args) throws InterruptedException {        IncorrentVolatileInBoolean runnable = new IncorrentVolatileInBoolean();        Thread thread1 = new Thread(runnable);        Thread thread2 = new Thread(runnable);        thread1.start();        thread2.start();        //主线程等待子线程执行完毕        thread1.join();        thread2.join();        System.out.println(runnable.done);        System.out.println("运行次数 : "+runnable.atomicInteger.get());    }    @Override    public void run() {            for (int i = 0; i 

多次运行 , 可以看到 , 有时是返回true, 有时是返回的false

e78cc87a4e0b28e64ca6d8c299b2dee6.png
a224d1a206b9112f69d703e89f0ba000.png


总结: 无论这个变量是什么类型, 只要这个变量只是被赋值的, 而没有其他的操作, 例如对比, 或者取值等, 那么此时对于volatile是适用的. 原因有两点:
赋值是原子性的, volatile又保证了可见性.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值