您的位置:首页 > 编程语言 > Java开发

Java多线程-java.util.concurrent.atomic包原理解读

2015-12-27 17:56 274 查看
参考学习:http://blog.csdn.net/zhangerqing/article/details/43057799
多线程基本类型

AtomicReference

Atomic*

Atomic包是java.util.concurrent下的另一个专门为线程安全设计的Java包,包含多个原子操作类,但Atomic的线程安全是如何来实现的呢?
1、硬件同步策略

现在的处理器都支持多重处理,当然也包含多个处理器共享外围设备和内存,同时,加强了指令集以支持一些多处理的特殊需求。

特别是几乎所有的处理器都可以将其他处理器阻塞以便更新共享变量
2、Compare and swap(CAS)

当前的处理器基本都支持CAS,只不过每个厂家所实现的算法并不一样罢了,每一个CAS操作过程都包含三个运算符:一个内存地址V,

一个期望的值A和一个新值B,操作的时候如果这个地址上存放的值等于这个期望的值A,则将地址上的值赋为新值B,否则不做任何操作。

CAS的基本思路就是,如果这个地址上的值和期望的值相等,则给其赋予新值,否则不做任何事儿,但是要返回原值是多少。我们来看一个例子,

解释CAS的实现过程(并非真实的CAS实现)
3、实现的核心源码:

 /**

     * Atomically increments by one the current value.

     *

     * @return the updated value

     */

    public final int incrementAndGet() {

        for (;;) {

            int current = get();

            int next = current + 1;

            if (compareAndSet(current, next))

                return next;

        }

    }

    public final boolean compareAndSet(int expect, int update) {

        //使用unsafe的native方法,实现高效的硬件级别CAS 

        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);

    }

他比直接使用传统的java锁机制(阻塞的)有什么好处?

最大的好处就是可以避免多线程的优先级倒置和死锁情况的发生,当然高并发下的性能提升也是很重要的

4、CAS线程安全

说了半天,我们要回归到最原始的问题了:这样怎么实现线程安全呢?请大家自己先考虑一下这个问题,其实我们在语言层面是没有做任何同步的操作的,

大家也可以看到源码没有任何锁加在上面,可它为什么是线程安全的呢?这就是Atomic包下这些类的奥秘:语言层面不做处理,我们将其交给硬件—CPU和内存,

利用CPU的多处理能力,实现硬件层面的阻塞,再加上volatile变量的特性即可实现基于原子操作的线程安全。所以说,CAS并不是无阻塞,

只是阻塞并非在语言、线程方面,而是在硬件层面,所以无疑这样的操作会更快更高效!

5总结

虽然基于CAS的线程安全机制很好很高效,但要说的是,并非所有线程安全都可以用这样的方法来实现,这只适合一些粒度比较小,

如计数器这样的需求用起来才有效,否则也不会有锁的存在了


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: