AtomicXX VS. AtomicXXFieldUpdater

2018/03/10 Java

看Netty源代码或者Druid连接池代码发现有很多地方都使用到了AtomicLongFieldUpdater这个类,如Druid里面的JdbcSqlStat,Netty里面的DefaultChannelHandlerContext。

先看下面两段代码:

DefaultChannelHandlerContext部分代码

    private static final AtomicIntegerFieldUpdater<AbstractChannelHandlerContext> HANDLER_STATE_UPDATER =
           AtomicIntegerFieldUpdater.newUpdater(AbstractChannelHandlerContext.class, "handlerState");

    private static final int INIT = 0;

    private volatile int handlerState = INIT;

JdbcSqlStat类部分代码

    private volatile long                               executeBatchSizeTotal;
    private volatile int                                executeBatchSizeMax;

    private volatile long                               executeSuccessCount;
    private volatile long                               executeSpanNanoTotal;
    private volatile long                               executeSpanNanoMax;
    private volatile int                                runningCount;
    private volatile int                                concurrentMax;
    private volatile long                               resultSetHoldTimeNano;
    private volatile long                               executeAndResultSetHoldTime;

    final static AtomicLongFieldUpdater<JdbcSqlStat>    executeBatchSizeTotalUpdater                    = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class,
                                                                                                                                            "executeBatchSizeTotal");
    final static AtomicIntegerFieldUpdater<JdbcSqlStat> executeBatchSizeMaxUpdater                      = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class,
                                                                                                                                               "executeBatchSizeMax");

    final static AtomicLongFieldUpdater<JdbcSqlStat>    executeSuccessCountUpdater                      = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class,
                                                                                                                                            "executeSuccessCount");
    final static AtomicLongFieldUpdater<JdbcSqlStat>    executeSpanNanoTotalUpdater                     = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class,
                                                                                                                                            "executeSpanNanoTotal");
    final static AtomicLongFieldUpdater<JdbcSqlStat>    executeSpanNanoMaxUpdater                       = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class,
                                                                                                                                            "executeSpanNanoMax");
    final static AtomicIntegerFieldUpdater<JdbcSqlStat> runningCountUpdater                             = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class,
                                                                                                                                               "runningCount");
    final static AtomicIntegerFieldUpdater<JdbcSqlStat> concurrentMaxUpdater                            = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class,
                                                                                                                                               "concurrentMax");
    final static AtomicLongFieldUpdater<JdbcSqlStat>    resultSetHoldTimeNanoUpdater                    = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class,
                                                                                                                                            "resultSetHoldTimeNano");
    final static AtomicLongFieldUpdater<JdbcSqlStat>    executeAndResultSetHoldTimeUpdater              = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class,
                                                                                                                                            "executeAndResultSetHoldTime");

对于AtomicXXFieldUpdater这种类的作用及用法不多做解释。就是为了实现对volatile字段原子操作,那么实现原子操作我们为什么不选择AtomicInteger、AtomicLong、AtomicReference这种更好理解的类呢?

主要使用场景

大家考虑下在Netty这种系统里面会有大量的并发连接,而每一个并发连接都需要创建一个Channel,每一个Channel对应一个 ChannelPipeline,而一个ChannelPipeline对应由多个ChannelHandlerContext组成的链。这个时候就会有大量的ChannelHandlerContext实例存在,并且是长时间存活着的对象。这个时候使用AtomicXXFieldUpdater就比AtomicXX合适了。

为什么

因为这里多创建了一个AtomicXX对象,而在64位平台上每创建一个对象至少要花费16个Byte,如果这个数量特别大内存消耗可不小。

Search

    Table of Contents