Java并发之原子性

Java并发之原子性


1.什么是原子性

众所周知,原子是构成物质的基本单位,所以原子的意思代表着——“不可分”。

由不可分性可知,具有原子性的操作是拒绝线程调度器中断的。 简而言之——不被线程调度器中断的操作,如:

赋值或者return。比如”a = 1;”和 “return a;”这样的操作都具有原子性。


2.为什么需要原子性

现实情况是,“ i++; ”这个编程中很普通的一个操作都不具有原子性,这涉及到Java的内存模型。它在虚拟机中 操作 执行的顺序是

(1). 将变量从主存复制到工作内存(read,load)
(2). 执行代码,改变变量值(use,assign)
(3). 从工作内存同步回主存(store,write)

这里的操作是指括号中的read,write等由虚拟机实现的、具有原子性的操作。笔者分为(1)(2)(3)只是为了更简洁的描述这个过程。

这些操作之间是可以被线程调度器中断的。

下述例子本意是想用10个线程,每个线程都对inc自增1000,当程序结束时inc值能到10000。事实却是无论多少次运行程序,得到的都是小于10000的数。

该例可以说明,“ i++ ”语句执行期间,是可能会被线程调度器中断的。可以想象一种情况:当一个线程读inc变量进其工作内存后,被调度器切换,另一个线程马上又读inc进它的的工作内存,毫无疑问,这两个线程所有剩下操作执行完后,得到的是相同的结果,在程序上体现的是,两次自增计算只表现为一次。


public class Atomicity  {

    private volatile boolean canceled = false;
    private int inc = 0;

    public void increase() {
        inc++;
    }

    public static void main(String[] args) {

        final Atomicity a = new Atomicity ();
        ExecutorService service = Executors.newCachedThreadPool();

        for (int i = 0; i < 10; i++)
            service.execute(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++)
                        a.increase();
                }
            });
        service.shutdown();

        while (!a.canceled) {
            if (service.isTerminated()) {
                a.canceled = true;
            } else {
                Thread.yield();
            }
        }

        System.out.println(a.inc);
    }

    public boolean isCanceled() {
        return canceled;
    }

    public void setCanceled(boolean canceled) {
        this.canceled = canceled;
    }
}

这里的 volatile 修饰变量是为了保证此变量在多个线程之间的可见性,即一个线程对变量的修改会立即让其他所有线程知晓。关于可见行在下篇文章论述。

到这里,在并发情况下非原子性的操作引发的问题便初窥一角。程序要提供一种办法去保证代码运行结果在并发环境中的正确性。


3.如何保证原子性

(1)synchronized关键字
(2)Lock对象
(3)原子类

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值