猿类分阶:1~9 依次上升
一阶猿类
publicclassCounter1 { privatestaticintcnt=0; publicintincrease() { return++cnt; } publicintdecrease() { return--cnt; } }
旁白:实现了功能。
二阶猿类
publicclassCounter2 { privatestaticlongcnt=0; publiclongincrease() { return++cnt; } publiclongdecrease() { return--cnt; } }
旁白:考虑了 int 的范围限制,long 的范围更广泛。
三阶猿类
publicclassCounter3 { privatestaticlongcnt=0; publicsynchronizedlongincrease() { return++cnt; } publicsynchronizedlongdecrease() { return--cnt; } }
旁白:考虑了并发环境下的执行。
四阶猿类
publicclassCounter4 { privatestaticAtomicLongcnt=newAtomicLong(0); publiclongincrease() { returncnt.getAndIncrement(); } publiclongdecrease() { returncnt.getAndDecrement(); } }
旁白:考虑了并发环境下的 CAS 性能更优。
五阶猿类
publicclassCounter5 { privatestaticLongAddercnt=newLongAdder(); publiclongincrease() { cnt.increment(); returncnt.longValue(); } publiclongdecrease() { cnt.decrement(); returncnt.longValue(); } }
旁白:在单线程下,并发问题没有暴露,两者没有体现出差距;随着并发量加大,LongAdder 的 increment 操作更加优秀,而 AtomicLong 的 get 操作则更加优秀。鉴于在计数器场景下的特点—写多读少,所以写性能更高的 LongAdder 更加适合。
六阶猿类
publicclassCounter6 { privatestaticJdbcTemplateUtilsjdbc=newJdbcTemplateUtils();//JdbcTemplateUtils封装了jdbc的调用privatestaticlongcnt=0; publiclongincrease() { cnt=jdbc.getCnt(); returnjdbc.setCnt(++cnt); } publiclongdecrease() { cnt=jdbc.getCnt(); returnjdbc.setCnt(--cnt);; } }
旁白:考虑了在集群环境下保证数据的唯一性和一致性。
七阶猿类
publicclassCounter7 { privatestaticRedisclusterUtilsredis=newRedisclusterUtils();//RedisclusterUtils封装了Rediscluster的client功能privatestaticlongcnt=0; publiclongincrease() { returnredis.incr(cnt); } publiclongdecrease() { returnredis.decr(cnt);; } }
旁白:考虑了计数器集群下的并发性能问题,同样的实现可以使用 zk 或者 mongo 等内存数据库。
注:ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 Hbase 的重要组件。MongoDB 是一个基于分布式文件存储的数据库。
八阶猿类
publicclassCounter8 { privatestaticJdbcTempalteUtilsjdbc=newJdbcTempalteUtils(); privatestaticRedisclusterUtilsredis=newRedisclusterUtils(); privatestaticlongcnt=0; publiclongincrease() { if(redis.exsits(cnt)) { returnredis.incr(cnt); } cnt=jdbc.getCnt(key); ++cnt; redis.set(key,cnt); returncnt; } publiclongdecrease() { if(redis.exsits(cnt)) { returnredis.decr(cnt); } cnt=jdbc.getCnt(key); --cnt; redis.set(key,cnt); returncnt; } }
旁白:考虑到 Redis 宕机或者不可用的情况下的处理,有备份方案。
九阶猿类
这个要免考的。
