本故事纯属虚构,如有雷同,纯属巧合!
故事背景
悟空师徒4人取经回来后,因不耐收到管教,就回到了花果山,带领一帮猴子猴孙逍遥自在的过日子,奈何因在阎王殿里将生死薄中的猴子猴孙的名字都划去了,猴子猴孙是越来越多。
悟空是没有耐心的,无法一一管教,随向太白金星讨教。
猿类分级考试
太白金星给了主意:考试分级。
并且给出了题目:
创建一个通用的计数器,能计量很多的东西,如金箍棒。
参考答案如下:
猿类分阶:一~九等级 依次上升
一阶猿类
publicclass Counter1 {
privatestaticintcnt=0;
publicint increase() {
return++cnt;
}
publicint decrease() {
return--cnt;
}
}
旁白:实现了功能。
二阶猿类
publicclass Counter2 {
privatestaticlongcnt=0;
publiclong increase() {
return++cnt;
}
publiclong decrease() {
return--cnt;
}
}
旁白:考虑了int的范围限制,long的范围更广泛。
三阶猿类
publicclass Counter3 {
privatestaticlongcnt=0;
publicsynchronizedlong increase() {
return++cnt;
}
publicsynchronizedlong decrease() {
return--cnt;
}
}
旁白:考虑了并发环境下的执行
四阶猿类
publicclass Counter4 {
privatestaticAtomicLong cnt=newAtomicLong(0);
publiclong increase() {
return cnt.getAndIncrement();
}
publiclong decrease() {
return cnt.getAndDecrement();
}
}
旁白:考虑了并发环境下的cas性能更优
五阶猿类
publicclass Counter5 {
privatestaticLongAdder cnt=new LongAdder();
publiclong increase() {
cnt.increment();
return cnt.longValue();
}
publiclong decrease() {
cnt.decrement();
return cnt.longValue();
}
}
旁白:在单线程下,并发问题没有暴露,两者没有体现出差距;随着并发量加大,LongAdder 的 increment 操作更加,而 AtomicLong 的 get 操作则更加。鉴于在计数器场景下的特点—写多读少,所以写性能更高的 LongAdder 更加适合。
六阶猿类
publicclass Counter6 {
privatestaticJdbcTemplateUtils jdbc=new JdbcTemplateUtils();
privatestaticlongcnt=0;
publiclong increase() {
cnt=jdbc.getCnt();
returnjdbc.setCnt(++cnt);
}
publiclong decrease() {
cnt=jdbc.getCnt();
returnjdbc.setCnt(--cnt);;
}
}
旁白:考虑了在集群环境下保证数据的性和一致性。
七阶猿类
publicclass Counter7 {
privatestaticRedisclusterUtils redis=new RedisclusterUtils();
privatestaticlongcnt=0;
publiclong increase() {
return redis.incr(cnt);
}
publiclong decrease() {
return redis.decr(cnt);;
}
}
旁白:考虑了计数器集群下的并发性能问题,同样的实现可以使用zk或者mongo等内存数据库。
八阶猿类
publicclass Counter8 {
privatestaticJdbcTempalteUtils jdbc=new JdbcTempalteUtils();
privatestaticRedisclusterUtils redis=new RedisclusterUtils();
privatestaticlongcnt=0;
publiclong increase() {
if(redis.exsits(cnt)) {
return redis.incr(cnt);
}
cnt=jdbc.getCnt(key);
++cnt;
redis.set(key,cnt);
return cnt;
}
publiclong decrease() {
if(redis.exsits(cnt)) {
return redis.decr(cnt);
}
cnt=jdbc.getCnt(key);
--cnt;
redis.set(key,cnt);
return cnt;
}
}
旁白:考虑到redis宕机或者不可用的情况下的处理,有备份方案。
九阶猿类
这个要免考的。