【Java】AtomicReference原子性引用

AtomicReference

AtomicStampReference 安全的修改一个变量的值

package com.keytech.task;

import org.junit.platform.commons.logging.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;

import java.util.concurrent.atomic.AtomicReference;

/**

* @className: AtomicIntegerTest

* @description: TODO 类描述

* @author: mac

* @date: 2020/12/29

**/

//线程安全

public class AtomicIntegerTest {

private static AtomicReference<Integer> count=new AtomicReference<>(0);

public static void main(String[] args) {

//如果期望值是0,则修改成2

count.compareAndSet(0, 2); //ok

//如果期望值是1,则修改成4

count.compareAndSet(1, 4); //no ok

//如果期望值是2,则修改成8

count.compareAndSet(2, 8); //ok

System.out.println(count.get());

}

}

//输出8

如果AtomicReference<T>T是一个自定义的对象,线程安全?

public class AtomicReference<V> implements java.io.Serializable {

private static final long serialVersionUID = -1848883965231344442L;

private static final Unsafe unsafe = Unsafe.getUnsafe();

private static final long valueOffset;

static {

try {

valueOffset = unsafe.objectFieldOffset

(AtomicReference.class.getDeclaredField("value"));

} catch (Exception ex) { throw new Error(ex); }

}

private volatile V value;

/**

* Creates a new AtomicReference with the given initial value.

*

* @param initialValue the initial value

*/

public AtomicReference(V initialValue) {

value = initialValue;

}

/**

* Creates a new AtomicReference with null initial value.

*/

public AtomicReference() {

}

/**

* 不需要安全防护

*/

public final V get() {

return value;

}

/**

* 设值值不需要进行对象安全防护

*/

public final void set(V newValue) {

value = newValue;

}

/**

* 很明显调用的是csa操作

* 比较对象是否相同,进行设值

* 设值成功返回true,否则返回false

*/

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

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

}

/**

* 设置新的值并且返回旧的值

* 原子操作

*/

@SuppressWarnings("unchecked")

public final V getAndSet(V newValue) {

return (V)unsafe.getAndSetObject(this, valueOffset, newValue);

}

}

AtomicReference不安全的修改自定义对象属性的值

package com.keytech.task;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Semaphore;

import java.util.concurrent.atomic.AtomicReference;

/**

* @className: AtomicReferenceTest

* @description: TODO 类描述

* @author: mac

* @date: 2020/12/29

**/

public class AtomicReferenceTest {

private static Integer clientTotal=5000;

private static Integer threadTotal=200;

private static Rumenz rumenz=new Rumenz(0,0);

private static AtomicReference<Rumenz> rumenzReference=new AtomicReference<>(rumenz);

public static void main(String[] args) {

ExecutorService executorService = Executors.newCachedThreadPool();

Semaphore semaphore=new Semaphore(threadTotal);

for (int i = 0; i < clientTotal; i++) {

final Integer n=i;

executorService.execute(()->{

try{

semaphore.acquire();

update(n);

semaphore.release();

}catch (Exception e){

e.printStackTrace();

}

});

}

executorService.shutdown();

System.out.println("rumenzReference="+rumenzReference.get().getAge());

System.out.println("rumenzReference="+rumenzReference.get().getName());

}

//如果线程安全的话,age的值和name的值是一致的

//如果线程不安全的话,age的值和name是不一样的。

private static void update(int i){

rumenzReference.get().setAge(rumenzReference.get().getAge()+i);

rumenzReference.get().setName(rumenzReference.get().getName()+i);

}

}

class Rumenz{

private Integer age;

private Integer name;

public Rumenz(Integer age, Integer name) {

this.age = age;

this.name = name;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public Integer getName() {

return name;

}

public void setName(Integer name) {

this.name = name;

}

}

通过AtomicintegerFieldUpdater安全的修改自定义对象

AtomicIntegerFieldUpdater

package com.keytech.task;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**

* @className: AtomicIntegerFieldUpdaterTest

* @description: TODO 类描述

* @author: mac

* @date: 2020/12/29

**/

public class AtomicIntegerFieldUpdaterTest {

private static AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> upCount=AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class,"count");

public int getCount() {

return count;

}

public volatile int count=100;

public static void main(String[] args) {

AtomicIntegerFieldUpdaterTest obj=new AtomicIntegerFieldUpdaterTest();

if(upCount.compareAndSet(obj,100,200)){

System.out.println("修改成功"+obj.getCount());

}

if(upCount.compareAndSet(obj,100,200)){

System.out.println("修改成功");

}else{

System.out.println("修改失败");

}

}

}

//修改成功200

//修改失败

AtomicIntegerFieldUpdater源码分析

public abstract class AtomicIntegerFieldUpdater<T> {

/**

*

* @param tclass 持有某字段的类

* @param fieldName 字段名字

*/

@CallerSensitive

public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,

String fieldName) {

return new AtomicIntegerFieldUpdaterImpl<U>

(tclass, fieldName, Reflection.getCallerClass());

}

/**

* 原子性设置

*/

public int getAndSet(T obj, int newValue) {

int prev;

do {

prev = get(obj);

} while (!compareAndSet(obj, prev, newValue));

return prev;

}

private static class AtomicIntegerFieldUpdaterImpl<T>

extends AtomicIntegerFieldUpdater<T> {

private static final Unsafe unsafe = Unsafe.getUnsafe();

private final long offset;

private final Class<T> tclass;

private final Class<?> cclass;

AtomicIntegerFieldUpdaterImpl(final Class<T> tclass,

final String fieldName,

final Class<?> caller) {

final Field field;

final int modifiers;

try {

field = AccessController.doPrivileged(

new PrivilegedExceptionAction<Field>() {

public Field run() throws NoSuchFieldException {

//字段不存在会抛异常

return tclass.getDeclaredField(fieldName);

}

});

//检查访问级别

modifiers = field.getModifiers();

sun.reflect.misc.ReflectUtil.ensureMemberAccess(

caller, tclass, null, modifiers);

ClassLoader cl = tclass.getClassLoader();

ClassLoader ccl = caller.getClassLoader();

if ((ccl != null) && (ccl != cl) &&

((cl == null) || !isAncestor(cl, ccl))) {

sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);

}

} catch (PrivilegedActionException pae) {

throw new RuntimeException(pae.getException());

} catch (Exception ex) {

throw new RuntimeException(ex);

}

Class<?> fieldt = field.getType();

//必须是int

if (fieldt != int.class)

throw new IllegalArgumentException("Must be integer type");

//必须用volatile修饰

if (!Modifier.isVolatile(modifiers))

throw new IllegalArgumentException("Must be volatile type");

this.cclass = (Modifier.isProtected(modifiers) &&

caller != tclass) ? caller : null;

this.tclass = tclass;

//用Unsafe里的那一坨方法去原子更新

offset = unsafe.objectFieldOffset(field);

}

}

}

AtomicIntegerFieldUpdater线程安全的更新自定义对象的属性值

package com.keytech.task;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Semaphore;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**

* @className: AtomicReferenceTest

* @description: TODO 类描述

* @author: mac

* @date: 2020/12/29

**/

public class AtomicReferenceTest {

private static Integer clientTotal=5000;

private static Integer threadTotal=200;

public static Rumenz rumenz=new Rumenz(0,0);

public static AtomicIntegerFieldUpdater<Rumenz> rumenzReferenceAge= AtomicIntegerFieldUpdater.newUpdater(Rumenz.class,"age");

private static AtomicIntegerFieldUpdater<Rumenz> rumenzReferenceName= AtomicIntegerFieldUpdater.newUpdater(Rumenz.class,"name");

public static void main(String[] args) {

ExecutorService executorService = Executors.newCachedThreadPool();

Semaphore semaphore=new Semaphore(threadTotal);

for (int i = 0; i < clientTotal; i++) {

final Integer n=i;

executorService.execute(()->{

try{

semaphore.acquire();

update(n);

semaphore.release();

}catch (Exception e){

e.printStackTrace();

}

});

}

executorService.shutdown();

System.out.println("rumenzReference="+ rumenz.getAge());

System.out.println("rumenzReference="+ rumenz.getName());

}

public static void update(int i){

rumenzReferenceAge.incrementAndGet(rumenz);

rumenzReferenceName.incrementAndGet(rumenz);

}

}

class Rumenz{

//必须加volatile 如果是整数不能写包装类型:如不能为Integer

public volatile int age;

public volatile int name;

public Rumenz(Integer age, Integer name) {

this.age = age;

this.name = name;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public Integer getName() {

return name;

}

public void setName(Integer name) {

this.name = name;

}

}

//rumenzReference=5000

//rumenzReference=5000

【Java】AtomicReference原子性引用

以上是 【Java】AtomicReference原子性引用 的全部内容, 来源链接: utcz.com/a/90824.html

回到顶部