线程间数据共享

多线程对一个变量操作时,需要注意线程安全。

线程不安全

static  int num = 0;

public static void main(String[] args) {
    for (int i = 0; i < 6; i++) {
        new Thread(() -> {
            try {
                num = num + 2;
                System.out.println("num = " + num);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
}

执行结果:
在这里插入图片描述

线程安全

1, volatile
volatile 变量,用来确保将变量的更新操作通知到其他线程。

static volatile int num = 0;

public static void main(String[] args) {
    for (int i = 0; i < 6; i++) {
        new Thread(() -> {
            try {
                num = num + 2;
                System.out.println("num = " + num);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
}

执行结果:
在这里插入图片描述
当对非 volatile 变量进行读写的时候,每个线程先从内存拷贝变量到 CPU 缓存中。如果计算机有多个 CPU,每个线程可能在不同的 CPU 上被处理,这意味着每个线程CPU cache 中的值可能会不一致。
在这里插入图片描述
声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读,跳过 CPU cache 这一步。每个线程更新变量都会改变内容中的值,所以每个线程可以从内存中获取最新的值。
2,Atomic 类型的变量 - AtomicInteger


    public static void main(String[] args) {
        AtomicInteger num = new AtomicInteger();
        for (int i = 0; i < 6; i++) {
            new Thread(() -> {
                try {
                    num.set(num.get() + 2);
                    System.out.println("num = " + num);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

运行结果:
在这里插入图片描述
AtomicInteger ,一个提供原子操作的 Integer 的类,常见的还有AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference 等,他们的实现原理相同,区别在与运算对象类型的不同。令人兴奋地,还可以通过 AtomicReference将一个对象的所有操作转化成原子操作.

3,将数据抽象成一个类,并将数据的操作作为这个类的方法,在方法上加 synchronized


    public static void main(String[] args) {
        NumOperation num = new NumOperation(0);
        for (int i = 0; i < 6; i++) {
            new Thread(() -> {
                try {
                    System.out.println("num = " + num.plus(2));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

    static class NumOperation {
        private Integer num;

        public NumOperation(Integer num) {
            this.num = num;
        }

        public synchronized Integer plus(Integer val) {
            this.num = this.num + val;
            return num;
        }

        public synchronized Integer minus(Integer val) {
            this.num = this.num - val;
            return num;
        }

        public Integer getNum() {
            return num;
        }
    }

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值