apache mina : 用户自定义数据存储
来源:互联网 发布:java获取项目路径 编辑:程序博客网 时间:2024/06/05 07:52
Stores the user-defined attributes which is provided per IoSession. All user-defined attribute accesses in IoSession are forwarded to the instance of IoSessionAttributeMap.
public interface IoSessionAttributeMap { Object getAttribute(IoSession session, Object key, Object defaultValue); Object setAttribute(IoSession session, Object key, Object value); Object setAttributeIfAbsent(IoSession session, Object key, Object value); Object removeAttribute(IoSession session, Object key); boolean removeAttribute(IoSession session, Object key, Object value); boolean replaceAttribute(IoSession session, Object key, Object oldValue, Object newValue); boolean containsAttribute(IoSession session, Object key); Set<Object> getAttributeKeys(IoSession session); void dispose(IoSession session) throws Exception;}
private static class DefaultIoSessionAttributeMap implements IoSessionAttributeMap {
private final ConcurrentHashMap<Object, Object> attributes = new ConcurrentHashMap<Object, Object>(4);
}
在DefaultIoSessionDataStructureFactory 类中,使用ConcurrentHashMap 来保存用户自定义数据。
public final class AttributeKey implements Serializable { /** The serial version UID */ private static final long serialVersionUID = -583377473376683096L; /** The attribute's name */ private final String name; public AttributeKey(Class<?> source, String name) { this.name = source.getName() + '.' + name + '@' + Integer.toHexString(this.hashCode()); }}
使用AttributeKey 作为键。
在看看在netty 中是如何保存用户自定义数据的。
/** * Holds {@link Attribute}s which can be accessed via {@link AttributeKey}. * * Implementations must be Thread-safe. */public interface AttributeMap { /** * Get the {@link Attribute} for the given {@link AttributeKey}. This method will never return null, but may return * an {@link Attribute} which does not have a value set yet. */ <T> Attribute<T> attr(AttributeKey<T> key); /** * Returns {@code} true if and only if the given {@link Attribute} exists in this {@link AttributeMap}. */ <T> boolean hasAttr(AttributeKey<T> key);}
public class DefaultAttributeMap implements AttributeMap { @SuppressWarnings("rawtypes") private static final AtomicReferenceFieldUpdater<DefaultAttributeMap, AtomicReferenceArray> updater; static { @SuppressWarnings("rawtypes") AtomicReferenceFieldUpdater<DefaultAttributeMap, AtomicReferenceArray> referenceFieldUpdater = PlatformDependent.newAtomicReferenceFieldUpdater(DefaultAttributeMap.class, "attributes"); if (referenceFieldUpdater == null) { referenceFieldUpdater = AtomicReferenceFieldUpdater .newUpdater(DefaultAttributeMap.class, AtomicReferenceArray.class, "attributes"); } updater = referenceFieldUpdater; } private static final int BUCKET_SIZE = 4; private static final int MASK = BUCKET_SIZE - 1; // Initialize lazily to reduce memory consumption; updated by AtomicReferenceFieldUpdater above. @SuppressWarnings("UnusedDeclaration") private volatile AtomicReferenceArray<DefaultAttribute<?>> attributes;}
在Netty中默认AttributeMap是线程安全的,当AttributeMap被多个线程访问时,可以做到线程安全。
/** * Key which can be used to access {@link Attribute} out of the {@link AttributeMap}. Be aware that it is not be * possible to have multiple keys with the same name. * * @param <T> the type of the {@link Attribute} which can be accessed via this {@link AttributeKey}. */@SuppressWarnings("UnusedDeclaration") // 'T' is used only at compile timepublic final class AttributeKey<T> extends AbstractConstant<AttributeKey<T>> { private static final ConstantPool<AttributeKey<Object>> pool = new ConstantPool<AttributeKey<Object>>() { @Override protected AttributeKey<Object> newConstant(int id, String name) { return new AttributeKey<Object>(id, name); } }; /** * Returns the singleton instance of the {@link AttributeKey} which has the specified {@code name}. */ @SuppressWarnings("unchecked") public static <T> AttributeKey<T> valueOf(String name) { return (AttributeKey<T>) pool.valueOf(name); } /** * Returns {@code true} if a {@link AttributeKey} exists for the given {@code name}. */ public static boolean exists(String name) { return pool.exists(name); } /** * Creates a new {@link AttributeKey} for the given {@param name} or fail with an * {@link IllegalArgumentException} if a {@link AttributeKey} for the given {@param name} exists. */ @SuppressWarnings("unchecked") public static <T> AttributeKey<T> newInstance(String name) { return (AttributeKey<T>) pool.newInstance(name); } @SuppressWarnings("unchecked") public static <T> AttributeKey<T> valueOf(Class<?> firstNameComponent, String secondNameComponent) { return (AttributeKey<T>) pool.valueOf(firstNameComponent, secondNameComponent); } private AttributeKey(int id, String name) { super(id, name); }}
/** * An attribute which allows to store a value reference. It may be updated atomically and so is thread-safe. * * @param <T> the type of the value it holds. */public interface Attribute<T> { /** * Returns the key of this attribute. */ AttributeKey<T> key(); /** * Returns the current value, which may be {@code null} */ T get(); /** * Sets the value */ void set(T value); /** * Atomically sets to the given value and returns the old value which may be {@code null} if non was set before. */ T getAndSet(T value); /** * Atomically sets to the given value if this {@link Attribute}'s value is {@code null}. * If it was not possible to set the value as it contains a value it will just return the current value. */ T setIfAbsent(T value); /** * Removes this attribute from the {@link AttributeMap} and returns the old value. Subsequent {@link #get()} * calls will return {@code null}. * * If you only want to return the old value and clear the {@link Attribute} while still keep it in * {@link AttributeMap} use {@link #getAndSet(Object)} with a value of {@code null}. */ T getAndRemove(); /** * Atomically sets the value to the given updated value if the current value == the expected value. * If it the set was successful it returns {@code true} otherwise {@code false}. */ boolean compareAndSet(T oldValue, T newValue); /** * Removes this attribute from the {@link AttributeMap}. Subsequent {@link #get()} calls will return @{code null}. * * If you only want to remove the value and clear the {@link Attribute} while still keep it in * {@link AttributeMap} use {@link #set(Object)} with a value of {@code null}. */ void remove();}
public abstract class AbstractChannel extends DefaultAttributeMap implements Channel {
}
所有NioChannel的抽象基类
public abstract class AbstractNioChannel extends AbstractChannel {
}
所有NioByteChannel的抽象基类
public abstract class AbstractNioByteChannel extends AbstractNioChannel {
}
public class NioServerSocketChannel extends AbstractNioMessageChannel
implements io.netty.channel.socket.ServerSocketChannel {
}
public class NioSocketChannel extends AbstractNioByteChannel implements io.netty.channel.socket.SocketChannel {
}
从整体的设计与实现,每一次Netty都是在apache mina 之上的提升和优化, 也许会更加的简单方便。可以是因为先入为主的原因,总感觉apache mina实现的更加简单,容易上手学习。
- apache mina : 用户自定义数据存储
- Apache Mina 自定义协议
- apache mina 自定义协议
- apache mina: 写数据过程
- Apache Mina自定义编解码案例
- Apache Mina自定义编解码案例 .
- Apache Mina自定义编解码案例
- Java - Apache Mina 自定义协议通信
- Apache Mina自定义编解码案例
- Apache Mina自定义编解码案例 .
- APACHE MINA之自定义CODEC(编码/解码)
- Apache 自定义用户认证
- Mina自定义协议-实现数据交互
- Apache Mina
- Apache Mina
- Apache Mina
- Apache Mina
- apache mina
- 2016年3月 TIOBE 编程语言排行榜
- Codeforces #345 Div.2 A Joysticks 暴力模拟
- UISearchBar的光标
- 关于ListView 中有head的时候,有事件要处理的时候,
- 开发Windows性能计数器提供程序
- apache mina : 用户自定义数据存储
- 详解Nginx配置nginx.conf
- [leetcode] 235. Lowest Common Ancestor of a Binary Search Tree
- node.js微信开发《一》
- 开始写博客了(´・_・`)
- Java网络编程(一)流
- iOS中UIViewController生命周期和响应者链
- PAT_Basic 1019
- Swift的一些基本属性3 (可选项)