本故事纯属虚构,如有雷同,纯属巧合!

故事背景

花果山第一届猿类分级考试实录--根据计数器实现判断猿类的级别

 

悟空师徒4人取经回来后,因不耐收到管教,就回到了花果山,带领一帮猴子猴孙逍遥自在的过日子,奈何因在阎王殿里将生死薄中的猴子猴孙的名字都划去了,猴子猴孙是越来越多。

花果山第一届猿类分级考试实录--根据计数器实现判断猿类的级别

 

悟空最是没有耐心的,无法一一管教,随向太白金星讨教。

花果山第一届猿类分级考试实录--根据计数器实现判断猿类的级别

 

猿类分级考试

太白金星给了主意:考试分级。

并且给出了题目:

创建一个通用的计数器,能计量很多的东西,如金箍棒。

花果山第一届猿类分级考试实录--根据计数器实现判断猿类的级别

 

参考答案如下:

猿类分阶:一~九等级 依次上升

一阶猿类

public class Counter1 {
    private static int cnt=0;
    
    public int increase() {
        return ++cnt;
    }
    
    public int decrease() {
        return --cnt;
    }    
    
}

 

旁白:实现了功能。

二阶猿类

public class Counter2 {
    private static long cnt=0;
    
    public long increase() {
        return ++cnt;
    }
    
    public long decrease() {
        return --cnt;
    }        
}

 

旁白:考虑了int的范围限制,long的范围更广泛。

三阶猿类

public class Counter3 {
    private static long cnt=0;
    
    public synchronized long increase() {
        return ++cnt;
    }
    
    public synchronized long decrease() {
        return --cnt;
    }        
}

 

旁白:考虑了并发环境下的执行

四阶猿类

public class Counter4 {
    private static AtomicLong cnt=new AtomicLong(0);
    
    public long increase() {
        return cnt.getAndIncrement();
    }
    
    public long decrease() {
        return cnt.getAndDecrement();
    }        
}

 

旁白:考虑了并发环境下的cas性能更优

五阶猿类

public class Counter5 {
    private static LongAdder cnt=new LongAdder();
    
    public long increase() {
        cnt.increment();
        return cnt.longValue();
    }
    
    public long decrease() {
         cnt.decrement();
         return cnt.longValue();
    }        
}

 

旁白:在单线程下,并发问题没有暴露,两者没有体现出差距;随着并发量加大,LongAdder 的 increment 操作更加优秀,而 AtomicLong 的 get 操作则更加优秀。鉴于在计数器场景下的特点—写多读少,所以写性能更高的 LongAdder 更加适合。

六阶猿类

public class Counter6 {
    private static JdbcTemplateUtils jdbc=new JdbcTemplateUtils();
    private static long cnt=0;
    
    public long increase() {
        cnt=jdbc.getCnt();    
        return jdbc.setCnt(++cnt);
    }
    
    public long decrease() {
         cnt=jdbc.getCnt();
         return jdbc.setCnt(--cnt);;
    }        
}

 

旁白:考虑了在集群环境下保证数据的唯一性和一致性。

七阶猿类

public class Counter7 {
    private static RedisclusterUtils redis=new RedisclusterUtils();
    private static long cnt=0;
    
    public long increase() {    
        return redis.incr(cnt);
    }
    
    public long decrease() {
         return redis.decr(cnt);;
    }        
}

 

旁白:考虑了计数器集群下的并发性能问题,同样的实现可以使用zk或者mongo等内存数据库。

八阶猿类

public class Counter8 {
    private static JdbcTempalteUtils jdbc=new JdbcTempalteUtils();
    private static RedisclusterUtils redis=new RedisclusterUtils();
    private static long cnt=0;
    
    public long increase() {    
        if(redis.exsits(cnt)) {
            return redis.incr(cnt);
        }
        cnt=jdbc.getCnt(key);
        ++cnt;
        redis.set(key,cnt);
        
        return cnt;
    }
    
    public long decrease() {
        if(redis.exsits(cnt)) {
            return redis.decr(cnt);
        }
        cnt=jdbc.getCnt(key);
        --cnt;
        redis.set(key,cnt);
        
        return cnt;
    }        
}

 

旁白:考虑到redis宕机或者不可用的情况下的处理,有备份方案。

九阶猿类

这个要免考的。

花果山第一届猿类分级考试实录--根据计数器实现判断猿类的级别

 

参考资料:

【1】https://mp.weixin.qq.com/s/yAvJFZWxfKb38IDMjQd5zg

posted on 2019-09-19 17:00  一天不进步,就是退步  阅读(610)  评论(2编辑  收藏  举报