欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java并发编程之原子变量与非阻塞同步机制

程序员文章站 2024-03-02 22:03:16
1.非阻塞算法 非阻塞算法属于并发算法,它们可以安全地派生它们的线程,不通过锁定派生,而是通过低级的原子性的硬件原生形式 —— 例如比较和交换。非阻塞算法的设计与实现极为...

1.非阻塞算法

非阻塞算法属于并发算法,它们可以安全地派生它们的线程,不通过锁定派生,而是通过低级的原子性的硬件原生形式 —— 例如比较和交换。非阻塞算法的设计与实现极为困难,但是它们能够提供更好的吞吐率,对生存问题(例如死锁和优先级反转)也能提供更好的防御。使用底层的原子化机器指令取代锁,比如比较并交换(cas,compare-and-swap).

2.悲观技术

独占锁是一种悲观的技术.它假设最坏的情况发生(如果不加锁,其它线程会破坏对象状态),即使没有发生最坏的情况,仍然用锁保护对象状态.

3.乐观技术

依赖冲突监测.先更新,如果监测发生冲突发生,则放弃更新后重试,否则更新成功.现在处理器都有原子化的读-改-写指令,比如比较并交换(cas,compare-and-swap).

4.cas操作

cas有3个操作数,内存值v,旧的预期值a,要修改的新值b。当且仅当预期值a和内存值v相同时,将内存值v修改为b,否则什么都不做。cas典型使用模式是:首先从v中读取a,并根据a计算新值b,然后再通过cas以原子方式将v中的值由a变成b(只要在这期间没有任何线程将v的值修改为其他值)。

清单 3. 说明比较并交换的行为(而不是性能)的代码

复制代码 代码如下:

public class simulatedcas {
     private int value;

     public synchronized int getvalue() { return value; }

    public synchronized int compareandswap(int expectedvalue, int newvalue) {
         int oldvalue = value;
         if (value == expectedvalue)
             value = newvalue;
         return oldvalue;
     }
}


清单 4. 使用比较并交换实现计数器
复制代码 代码如下:

public class cascounter {
    private simulatedcas value;
    public int getvalue() {
        return value.getvalue();
    }
    public int increment() {
        int oldvalue = value.getvalue();
        while (value.compareandswap(oldvalue, oldvalue + 1) != oldvalue)
            oldvalue = value.getvalue();
        return oldvalue + 1;
    }
}

5.原子变量

原子变量支持不用锁保护就能原子性更新操作,其底层用cas实现。共有12个原子变量,可分为4组:标量类、更新器类、数组类以及复合变量类。最常用的原子变量就是标量类:atomicinteger、atomiclong、atomicboolean以及atomicreference。所有类型都支持cas。

6.性能比较:锁与原子变量

在中低程度的竞争下,原子变量能提供很高的可伸缩性,原子变量性能超过锁;而在高强度的竞争下,锁能够更有效地避免竞争,锁的性能将超过原子变量的性能。但在更真实的实际情况中,原子变量的性能将超过锁的性能。