Netty-源码分析 DefaultAttribute

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/nimasike/article/details/91164920

//此类继承AtomicReference,以原子方式存取变量
private static final class DefaultAttribute<T> extends AtomicReference<T> implements Attribute<T> {

	private static final long serialVersionUID = -2661411462200283011L;

	// The head of the linked-list this attribute belongs to
	//链表的头的引用
	private final DefaultAttribute<?> head;
	
	//Key
	private final AttributeKey<T> key;

	// Double-linked list to prev and next node to allow fast removal
	//链表数据结构,前一个的变量引用
	private DefaultAttribute<?> prev;
	//链表数据结构,后一个的变量引用
	private DefaultAttribute<?> next;

	// Will be set to true one the attribute is removed via getAndRemove() or remove()
	//当调用getAndRemove() or remove()俩个方法时设置为true
	private volatile boolean removed;

	DefaultAttribute(DefaultAttribute<?> head, AttributeKey<T> key) {
		this.head = head;
		this.key = key;
	}

	// Special constructor for the head of the linked-list.
	DefaultAttribute() {
		head = this;
		key = null;
	}

	@Override
	public AttributeKey<T> key() {
		return key;
	}

	//如果不存在value设设置新的value
	@Override
	public T setIfAbsent(T value) {
		//这里调用AtomicReference的compareAndSet,传入null和value
		//如果之前的值为null,则AtomicReference的值设置为value,并返回true
		//返回true说明设置成功,循环结束,方法返回null
		//返回false说明AtomicReference之前已经设置过value,那么返回oldvalue
		while (!compareAndSet(null, value)) {
			T old = get();
			if (old != null) {
				return old;
			}
		}
		return null;
	}

	//把AtomicReference的值设置为null,并且把自己从队列中移除,并且返回AtomicReference之前的value
	@Override
	public T getAndRemove() {
		removed = true;
		T oldValue = getAndSet(null);
		remove0();
		return oldValue;
	}

	//把AtomicReference的值设置为null,并且把自己从队列中移除
	@Override
	public void remove() {
		removed = true;
		set(null);
		remove0();
	}

	private void remove0() {
		//在头部对象上获取锁
		synchronized (head) {
			
			//如果前面引用为null,说明已经移除
			if (prev == null) {
				// Removed before.
				return;
			}

			//前面对象的next引用需要指向当前对象的next
			//因为链表结构,自己移除了,需要把前面对象和后面对象连接。...
			prev.next = next;

			//当前对象的next不为空的话,需要把next的prev设置为this.prev...
			if (next != null) {
				next.prev = prev;
			}

			// Null out prev and next - this will guard against multiple remove0() calls which may corrupt
			// the linked list for the bucket.
			//把自己的前后引用设置为空
			prev = null;
			next = null;
		}
	}
}

猜你喜欢

转载自blog.csdn.net/nimasike/article/details/91164920