并发读源码——AtomicIntegerFieldUpdater/AtomicLongFieldUpdater/AtomicReferenceFieldUpdater

1、AtomicIntegerFieldUpdater介绍

AtomicIntegerFieldUpdater与AtomicInteger什么区别呢?AtomicInteger可以保证内部的属性的操作时原子性的;AtomicIntegerFieldUpdater是保证其他类的属性的操作时原子性的。当一个类新建时,可以选型Atomic类型的原子类,但当对已经存在的一个类,如要保证内部的操作为原子性,就要借助AtomicIntegerFieldUpdater了。
但是AtomicIntegerFieldUpdater也有它的局限性,它处理的类中的属性必须保证是int类型的(不能是Integer包装类型)、必须是volatile类型的,否则不能用AtomicIntegerFieldUpdater来保证其原子性。

2、AtomicIntegerFieldUpdater原理

比如StoreHouse表示仓库储藏的类,其内部有一个属性num,表示货物的数量,当几个线程同时生产货物时,会导致num的线程不安全,AtomicIntegerFieldUpdater可以保证StoreHouse中的num的线程安全。首先AtomicIntegerFieldUpdater是通过反射StoreHouse获取到num的属性,然后后续操作与AtomicInteger中操作一致,通过CAS对num进行操作,底层调用了Unsafe的compareAndSwapInt函数,保证了线程安全性。

3、AtomicIntegerFieldUpdater源码解析

public abstract class AtomicIntegerFieldUpdater<T> {
	/*
	 * 通过newUpdate静态方法创建一个AtomicIntegerFieldUpdater的实例对象
	 * 但实际是创建的AtomicIntegerFieldUpdater子类AtomicIntegerFieldUpdaterImpl对象
	 * fieldName为tclass表示的类中的字段,AtomicIntegerFieldUpdater就是要保证fieldName的原子性
	 * */
	
	/*
	 * 凡是类或者方法上被标记了@CallerSensitive注解的,该类或者该方法所在的类的被标记该注解后,用Reflection.getCallerClass()反射获取
	 * 调用该类对象的上级类的对象,如果上级的类或方法中也标记了@CallerSensitive注解,就继续向上获取,直到获取没有标记@CallerSensitive的类,
	 * 此时Reflection.getCallerClass()获取的就是该类的class对象
	 * */
    @CallerSensitive
    public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,
                                                              String fieldName) {
        return new AtomicIntegerFieldUpdaterImpl<U>
            (tclass, fieldName, Reflection.getCallerClass());
    }

    /*由子类AtomicIntegerFieldUpdaterImpl实现方法*/
    protected AtomicIntegerFieldUpdater() {
    }

    /*由子类AtomicIntegerFieldUpdaterImpl实现方法*/
    public abstract boolean compareAndSet(T obj, int expect, int update);

    /*由子类AtomicIntegerFieldUpdaterImpl实现方法*/
    public abstract boolean weakCompareAndSet(T obj, int expect, int update);

    /*由子类AtomicIntegerFieldUpdaterImpl实现方法*/
    public abstract void set(T obj, int newValue);

    /*由子类AtomicIntegerFieldUpdaterImpl实现方法*/
    public abstract void lazySet(T obj, int newValue);

    /*由子类AtomicIntegerFieldUpdaterImpl实现方法*/
    public abstract int get(T obj);

    /*
     * obj为初始化时传入的对象,newValue为传入对象的属性
     * 该方法先获取对象中的属性值,然后用newValue新值更新到对象属性中
     * 设置newValue用了乐观锁的方式
     * */
    /*该方法一般不会被调用到,因为子类AtomicIntegerFieldUpdaterImpl重载了该方法*/
    public int getAndSet(T obj, int newValue) {
        int prev;
        do {
            prev = get(obj);
        } while (!compareAndSet(obj, prev, newValue));
        return prev;
    }

    /*先获取传入对象中的属性值,然后加1更新到属性中*/
    /*该方法一般不会被调用到,因为子类AtomicIntegerFieldUpdaterImpl重载了该方法*/
    public int getAndIncrement(T obj) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev + 1;
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

    /*先获取传入对象中属性值,然后减1更新到属性中*/
    /*该方法一般不会被调用到,因为子类AtomicIntegerFieldUpdaterImpl重载了该方法*/
    public int getAndDecrement(T obj) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev - 1;
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

    /*新获取传入对象中属性值,然后加delta更新到属性中*/
    /*该方法一般不会被调用到,因为子类AtomicIntegerFieldUpdaterImpl重载了该方法*/
    public int getAndAdd(T obj, int delta) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev + delta;
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

    /*先把传入对象中属性值加1更新到对象中,然后返回更新后的属性值*/
    /*该方法一般不会被调用到,因为子类AtomicIntegerFieldUpdaterImpl重载了该方法*/
    public int incrementAndGet(T obj) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev + 1;
        } while (!compareAndSet(obj, prev, next));
        return next;
    }

    /*先把传入对象中属性值减1更新到对象中,然后返回更新后的属性值*/
    /*该方法一般不会被调用到,因为子类AtomicIntegerFieldUpdaterImpl重载了该方法*/
    public int decrementAndGet(T obj) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev - 1;
        } while (!compareAndSet(obj, prev, next));
        return next;
    }

    /*先把传入对象中属性值加delta更新到对象中,然后返回更新后的属性值*/
    /*该方法一般不会被调用到,因为子类AtomicIntegerFieldUpdaterImpl重载了该方法*/
    public int addAndGet(T obj, int delta) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev + delta;
        } while (!compareAndSet(obj, prev, next));
        return next;
    }

    /*先获取传入对象中的属性值,然后把获取的属性值通过函数式方法处理后的值更新到属性中*/
    /*IntUnaryOperator接口中的applyAsInt方法,接受一个int参数,处理后返回一个int值,该函数式接口要在外部实现后出入进来*/
    public final int getAndUpdate(T obj, IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get(obj);
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

    /*先把传入对象中的属性值通过IntUnaryOperator函数式接口处理后的新值更新到对象中,然后返回新值*/
    public final int updateAndGet(T obj, IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get(obj);
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(obj, prev, next));
        return next;
    }

    /*同上,只是处理传入对象中属性值的函数式接口为IntBinaryOperator,接受两个int参数,处理后返回一个Int值*/
    public final int getAndAccumulate(T obj, int x,
                                      IntBinaryOperator accumulatorFunction) {
        int prev, next;
        do {
            prev = get(obj);
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

    /*上方法先获取然后更新,该方法先更新再获取*/
    public final int accumulateAndGet(T obj, int x,
                                      IntBinaryOperator accumulatorFunction) {
        int prev, next;
        do {
            prev = get(obj);
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSet(obj, prev, next));
        return next;
    }

    /*AtomicIntegerFieldUpdater的子类AtomicIntegerFieldUpdaterImpl*/
    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;
            /*通过反射的方式获取传入对象tclass中属性的fieldName的Field对象*/
            try {
                field = AccessController.doPrivileged(
                    new PrivilegedExceptionAction<Field>() {
                        public Field run() throws NoSuchFieldException {
                            return tclass.getDeclaredField(fieldName);
                        }
                    });
                /*传入tclass对象中fieldName属性一定要试试public形式的,如果是private或者protected形式的,在下面方式fullCheck中校验会失败
                 * 如果fieldName是public形式的,modifiers的值为65
                 * */
                modifiers = field.getModifiers();
                sun.reflect.misc.ReflectUtil.ensureMemberAccess(
                    caller, tclass, null, modifiers);
                ClassLoader cl = tclass.getClassLoader();
                ClassLoader ccl = caller.getClassLoader();
                /*个人不太明白理解:如果tclass的类加载器是bootstrap classloader或者tclass比调用AtomicIntegerFieldUpdater的caller的加载器高级,需要校验是否有加载tclass的权限*/
                /*一般tclass和caller都是用户自定义的,是application classloader来加载,不会进入该if分支*/
                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);
            }

            /*传入的对象的field属性一定要是int类型的*/
            Class<?> fieldt = field.getType();
            if (fieldt != int.class)
                throw new IllegalArgumentException("Must be integer type");

            /*传入的对象的field属性一定要是volatile类型的*/
            if (!Modifier.isVolatile(modifiers))
                throw new IllegalArgumentException("Must be volatile type");

            /*一般caller和tclass的加载器都是用户加载器,经三方运算后,this.cclass=null*/
            this.cclass = (Modifier.isProtected(modifiers) &&
                           caller != tclass) ? caller : null;
            this.tclass = tclass;
            /*获取feld属性在传入对象的类中的偏移量,最后根据偏移量更新属性*/
            offset = unsafe.objectFieldOffset(field);
        }

        /*
         * 如果second是first的父ClassLoader,则返回true,否则返回false
         * */
        private static boolean isAncestor(ClassLoader first, ClassLoader second) {
            ClassLoader acl = first;
            do {
                acl = acl.getParent();
                if (second == acl) {
                    return true;
                }
            } while (acl != null);
            return false;
        }

        private void fullCheck(T obj) {
        	/*obj一定要是tclass的实例对象*/
            if (!tclass.isInstance(obj))
                throw new ClassCastException();
            /*判断obj是否是cclass的实例对象*/
            if (cclass != null)
                ensureProtectedAccess(obj);
        }

        /*通过乐观锁的方式,更新obj对象中属性为新值update,前提该对象属性主内存中的值一定要等于expect*/
        public boolean compareAndSet(T obj, int expect, int update) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            return unsafe.compareAndSwapInt(obj, offset, expect, update);
        }

        /*跟新obj的offset属性时,不会插入内存屏障,不嫩保障offset的原子性,尽管offset的属性时volatile类型的*/
        public boolean weakCompareAndSet(T obj, int expect, int update) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            return unsafe.compareAndSwapInt(obj, offset, expect, update);
        }

        /*为obj的offset的属性设置新值newValue*/
        public void set(T obj, int newValue) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            unsafe.putIntVolatile(obj, offset, newValue);
        }

        /*不会立即把newValue的值刷入到主内存中,只能保证最终一致性*/
        public void lazySet(T obj, int newValue) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            unsafe.putOrderedInt(obj, offset, newValue);
        }

        /*获取obj对象的offset对应属性的值*/
        public final int get(T obj) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            return unsafe.getIntVolatile(obj, offset);
        }

        /*
         * 通过乐观锁方式,把newValue更新到obj的offset的对象中,更新成功返回true
         * */
        public int getAndSet(T obj, int newValue) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            return unsafe.getAndSetInt(obj, offset, newValue);
        }

        public int getAndIncrement(T obj) {
            return getAndAdd(obj, 1);
        }

        public int getAndDecrement(T obj) {
            return getAndAdd(obj, -1);
        }

        /*
         * 先获取obj对象的offset对应属性的值,然后把delta的值更新到offset对应的属性中
         * */
        public int getAndAdd(T obj, int delta) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            return unsafe.getAndAddInt(obj, offset, delta);
        }

        public int incrementAndGet(T obj) {
            return getAndAdd(obj, 1) + 1;
        }

        public int decrementAndGet(T obj) {
             return getAndAdd(obj, -1) - 1;
        }

        public int addAndGet(T obj, int delta) {
            return getAndAdd(obj, delta) + delta;
        }

        private void ensureProtectedAccess(T obj) {
            if (cclass.isInstance(obj)) {
                return;
            }
            throw new RuntimeException(
                new IllegalAccessException("Class " +
                    cclass.getName() +
                    " can not access a protected member of class " +
                    tclass.getName() +
                    " using an instance of " +
                    obj.getClass().getName()
                )
            );
        }
    }
}

4、AtomicIntegerFieldUpdater多线程用法

首先有一个已经存在的类,后期不能修改的,现在需要用AtomicIntegerFieldUpdater实现StoreHouse中num的原子性。其中StoreHouse代表货仓,num代表货仓中的货物,现在有三个生产机器(线程)同时生产货物,会同时更新num,最多只生产20个货物,需要保证其原子性。

package com.lzj.atomic.atomicintegerfieldupdater;

public class StoreHouse {
	public volatile int num;

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	@Override
	public String toString() {
		return "StoreHouse [num=" + num + "]";
	}
}
package com.lzj.atomic.atomicintegerfieldupdater;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

public class AtomicIntegerFieldUpdaterDemo {
    public static void main(String[] args){
    	AtomicIntegerFieldUpdater<StoreHouse> integerProxy = AtomicIntegerFieldUpdater.newUpdater(StoreHouse.class, "num");
    	StoreHouse storeHouse = new StoreHouse();
    	storeHouse.setNum(0); 		//设置初始货物数量为0
    	
    	int THRESHOLD = 20; 		//总共要生产20个货物
    	Runnable runnable = new Runnable() {
			@Override
			public void run() {
				int num;
				int newNum;
				while((num = storeHouse.getNum()) < THRESHOLD) {
					newNum = num + 1;
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if(integerProxy.compareAndSet(storeHouse, num, newNum)) {
						System.out.println(Thread.currentThread() + " : 生产第" + newNum + "个货物");
					}
				}
			}
		};
		
		Thread thread1 = new Thread(runnable);
		Thread thread2 = new Thread(runnable);
		Thread thread3 = new Thread(runnable);
		thread1.start();
		thread2.start();
		thread3.start();
		
    }
}

运行这三台机器,输出如下:

Thread[Thread-0,5,main] : 生产第1个货物
Thread[Thread-1,5,main] : 生产第2个货物
Thread[Thread-0,5,main] : 生产第3个货物
Thread[Thread-1,5,main] : 生产第4个货物
Thread[Thread-0,5,main] : 生产第5个货物
Thread[Thread-2,5,main] : 生产第6个货物
Thread[Thread-0,5,main] : 生产第7个货物
Thread[Thread-2,5,main] : 生产第8个货物
Thread[Thread-0,5,main] : 生产第9个货物
Thread[Thread-2,5,main] : 生产第10个货物
Thread[Thread-0,5,main] : 生产第11个货物
Thread[Thread-0,5,main] : 生产第12个货物
Thread[Thread-1,5,main] : 生产第13个货物
Thread[Thread-0,5,main] : 生产第14个货物
Thread[Thread-0,5,main] : 生产第15个货物
Thread[Thread-1,5,main] : 生产第16个货物
Thread[Thread-0,5,main] : 生产第17个货物
Thread[Thread-1,5,main] : 生产第18个货物
Thread[Thread-2,5,main] : 生产第19个货物
Thread[Thread-0,5,main] : 生产第20个货物

AtomicLongFieldUpdater和AtomicReferenceFieldUpdater与AtomicIntegerFieldUpdater的原理及用法完全一致,只是AtomicIntegerFieldUpdater处理的类中的属性时int类型的,而AtomicLongFieldUpdater处理的类中的属性是long类型的,AtomicReferenceFieldUpdater处理的属性时object类型的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值