Java多线程系列---“JUC原子类”06之 AtomicLongFieldUpdater原子类

转自:http://www.cnblogs.com/skywang12345/p/3514635.html (含部分修改)

概要

AtomicIntegerFieldUpdater, AtomicLongFieldUpdater和AtomicReferenceFieldUpdater这3个修改类的成员的原子类型的原理和用法相似。本章以对基本类型的原子类进行介绍。内容包括:

  • AtomicLongFieldUpdater介绍和函数列表
  • AtomicLongFieldUpdater示例
  • AtomicLongFieldUpdater源码分析(基于JDK1.7.0_40)

AtomicLongFieldUpdater介绍和函数列表

AtomicLongFieldUpdater可以对指定"类的 ‘volatile long‘类型的成员"进行原子更新。它是基于反射原理实现的。

AtomicLongFieldUpdater函数列表

// 受保护的无操作构造方法,供子类使用。
protected AtomicLongFieldUpdater()

// 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值。
long addAndGet(T obj, long delta)
// 如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值。
abstract boolean compareAndSet(T obj, long expect, long update)
// 以原子方式将此更新器管理的给定对象字段当前值减 1。
long decrementAndGet(T obj)
// 获取此更新器管理的在给定对象的字段中保持的当前值。
abstract long get(T obj)
// 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值。
long getAndAdd(T obj, long delta)
// 以原子方式将此更新器管理的给定对象字段当前值减 1。
long getAndDecrement(T obj)
// 以原子方式将此更新器管理的给定对象字段的当前值加 1。
long getAndIncrement(T obj)
// 将此更新器管理的给定对象的字段以原子方式设置为给定值,并返回旧值。
long getAndSet(T obj, long newValue)
// 以原子方式将此更新器管理的给定对象字段当前值加 1。
long incrementAndGet(T obj)
// 最后将此更新器管理的给定对象的字段设置为给定更新值。
abstract void lazySet(T obj, long newValue)
// 为对象创建并返回一个具有给定字段的更新器。
static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName)
// 将此更新器管理的给定对象的字段设置为给定更新值。
abstract void set(T obj, long newValue)
// 如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值。
abstract boolean weakCompareAndSet(T obj, long expect, long update)

举例说明:

 1 // LongTest.java的源码
 2 import java.util.concurrent.atomic.AtomicLongFieldUpdater;
 3
 4 public class LongFieldTest {
 5
 6     public static void main(String[] args) {
 7
 8         // 获取Person的class对象
 9         Class cls = Person.class;
10         // 新建AtomicLongFieldUpdater对象,传递参数是“class对象”和“long类型在类中对应的名称”
11         AtomicLongFieldUpdater mAtoLong = AtomicLongFieldUpdater.newUpdater(cls, "id");
12         Person person = new Person(12345678L);
13
14         // 比较person的"id"属性,如果id的值为12345678L,则设置为1000。
15         mAtoLong.compareAndSet(person, 12345678L, 1000);
16         System.out.println("id="+person.getId());
17     }
18 }
19
20 class Person {
21     volatile long id;
22     public Person(long id) {
23         this.id = id;
24     }
25     public void setId(long id) {
26         this.id = id;
27     }
28     public long getId() {
29         return id;
30     }
31 }

运行结果

id=1000

下面分析LongFieldTest.java的流程。

1. newUpdater()
newUpdater()的源码如下:

复制代码
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
    Class<?> caller = Reflection.getCallerClass();
    if (AtomicLong.VM_SUPPORTS_LONG_CAS)
        return new CASUpdater<U>(tclass, fieldName, caller);
    else
        return new LockedUpdater<U>(tclass, fieldName, caller);
}
复制代码
说明:newUpdater()的作用是获取一个AtomicIntegerFieldUpdater类型的对象。
它实际上返回的是CASUpdater对象,或者LockedUpdater对象;具体返回哪一个类取决于JVM是否支持long类型的CAS函数。CASUpdater和LockedUpdater都是AtomicIntegerFieldUpdater的子类,它们的实现类似。下面以CASUpdater来进行说明。

CASUpdater类的源码如下:

public boolean compareAndSet(T obj, long expect, long update) {
    if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
    return unsafe.compareAndSwapLong(obj, offset, expect, update);
}
说明:它实际上是通过CAS函数操作。如果类的long对象的值是expect,则设置它的值为update。 

原文地址:https://www.cnblogs.com/Hermioner/p/9905284.html

时间: 2024-08-29 23:40:15

Java多线程系列---“JUC原子类”06之 AtomicLongFieldUpdater原子类的相关文章

Java多线程系列--“JUC线程池”06之 Callable和Future

概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3544116.html Callable 和 Future 简介 Callable 和 Future 是比较有趣的一对组合.当我们需要获取线程的执行结果时,就需要用到它们.Callable用于产生结果,Future用于获取结果. 1. Callable Calla

Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3534050.html Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可

Java多线程系列--&ldquo;JUC锁&rdquo;04之 公平锁(二)

前面一章,我们学习了"公平锁"获取锁的详细流程:这里,我们再来看看"公平锁"释放锁的过程."公平锁"的获取过程请参考"Java多线程系列–"JUC锁"03之 公平锁(一)",锁的使用示例请参考"Java多线程系列–"JUC锁"02之 互斥锁ReentrantLock". 注意(01)这里是以"公平锁"来进行说明.(02)关于本章的术语,如"

Java多线程系列--“JUC锁”05之 非公平锁

获取非公平锁(基于JDK1.7.0_40) 非公平锁和公平锁在获取锁的方法上,流程是一样的:它们的区别主要表现在"尝试获取锁的机制不同".简单点说,"公平锁"在每次尝试获取锁时,都是采用公平策略(根据等待队列依次排序等待):而"非公平锁"在每次尝试获取锁时,都是采用的非公平策略(无视等待队列,直接尝试获取锁,如果锁是空闲的,即可获取状态,则获取锁).在前面的"Java多线程系列--"JUC锁"03之 公平锁(一)&q

Java多线程系列--“JUC集合”03之 CopyOnWriteArraySet

概要 本章是JUC系列中的CopyOnWriteArraySet篇.接下来,会先对CopyOnWriteArraySet进行基本介绍,然后再说明它的原理,接着通过代码去分析,最后通过示例更进一步的了解CopyOnWriteArraySet.内容包括:CopyOnWriteArraySet介绍CopyOnWriteArraySet原理和数据结构CopyOnWriteArraySet函数列表CopyOnWriteArraySet源码(JDK1.7.0_40版本)CopyOnWriteArraySet

Java多线程系列--“JUC集合”02之 CopyOnWriteArrayList

概要 本章是"JUC系列"的CopyOnWriteArrayList篇.接下来,会先对CopyOnWriteArrayList进行基本介绍,然后再说明它的原理,接着通过代码去分析,最后通过示例更进一步的了解CopyOnWriteArrayList.内容包括:CopyOnWriteArrayList介绍CopyOnWriteArrayList原理和数据结构CopyOnWriteArrayList函数列表CopyOnWriteArrayList源码分析(JDK1.7.0_40版本)Copy

Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock

ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为"独占锁". 顾名思义,ReentrantLock锁在同一个时间点只能被一个线程锁持有:而可重入的意思是,ReentrantLock锁,可以被单个线程多次获取.ReentrantLock分为"公平锁"和"非公平锁".它们的区别体现在获取锁的机制上是否公平."锁"是为了保护竞争资源,防止多个线程同时操作线程而出错,ReentrantLock在

Java多线程系列--“JUC线程池”01之 线程池架构

概要 前面分别介绍了"Java多线程基础"."JUC原子类"和"JUC锁".本章介绍JUC的最后一部分的内容——线程池.内容包括:线程池架构图线程池示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509903.html 线程池架构图 线程池的架构图如下: 1. Executor 它是"执行者"接口,它是来执行任务的.准确的说,Executor提供了execute()接口来执行

Java多线程系列--“JUC锁”04之 公平锁(二)

释放公平锁(基于JDK1.7.0_40) 1. unlock() unlock()在ReentrantLock.java中实现的,源码如下: public void unlock() { sync.release(1); } 说明:unlock()是解锁函数,它是通过AQS的release()函数来实现的.在这里,"1"的含义和"获取锁的函数acquire(1)的含义"一样,它是设置"释放锁的状态"的参数.由于"公平锁"是可重