我爱布朗熊 2022-11-04 17:24 采纳率: 79.4%
浏览 44
已结题

学习Redis全局ID自增的时候,为什么return的时候使用了或运算就可以了完成这个操作

我在学习ID全局生成器的时候,想生成下图这样的id模板,但是最后return出现了一个或运算我不太理解,
而且 long count = stringRedisTemplate.opsForValue().increment("icr:"+keyPrefix+":"+date);这条语句的执行结果只有1或者0,为什么 return timestamp<< COUNT_BITS | count; 就可以实现下面这个模板呢?

img



//基于Redis的id生成器
@Component
public class RedisWorker {
//   开始的一个时间戳
//    时间戳 指的就是Unix时间戳(Unix timestamp)。
//    它也被称为Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,
//    定义为从格林威治时间19700101000000秒起至现在的总秒数。
     private  static  final long BEGIN_TIMESTAPMP=1640995200L;
//   序列号的位数
     private  static  final int COUNT_BITS = 32;
     @Resource
     private StringRedisTemplate stringRedisTemplate;
    /**
     *
     * @param keyPrefix  前缀
     * @return
     */
    public long nextId(String keyPrefix){
//        1.生成时间戳     当前时间
        LocalDateTime now = LocalDateTime.now();
//           当前时间的秒数
        long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
//           计算一下时间戳
        long timestamp = nowSecond-BEGIN_TIMESTAPMP;

//        2.生成序列号   我们用的Redis中的String数据结构  increment是自增,括号可以填一个参数key
//             2.1获取当前日期,精确到Tina
        String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
//             2.2 自增长   我们在后面添加一个日期还是有好处的,每一天都是不同的key,当我们获取某一天的订单的时候也好查询,
//                         另外如果都是用同一个key的话,可能会超过232次方
        long count = stringRedisTemplate.opsForValue().increment("icr:"+keyPrefix+":"+date);
//        3.拼接并返回
//           借助位运算进行拼接,如果直接拼接的话就成字符串了
//           时间戳移动32位(因为我们定义的就是32位,定义为了一个常量) 后面空出来的32位(序列号)就补零
//           序列号采用或运算填充 后面32为刚开始为0,count可能为0也可能为1,不管是0还是1 都填入进去
        return timestamp<< COUNT_BITS | count;
    }

//   用下面这个方法可以获取当前的时间戳
//    public static void main(String[] args) {
////       得到2022年一月一号000秒这个时间
//        LocalDateTime time = LocalDateTime.of(2022, 1, 1, 0, 0, 0);
////       得到一个秒数  ZoneOffset.UTC是一个时间戳
//         long second =time.toEpochSecond(ZoneOffset.UTC);
//        System.out.println(second);
//    }


}
  • 写回答

2条回答 默认 最新

  • 涝山道士 2022-11-04 17:36
    关注

    timestamp时间戳向左位移32位,然后整体就变为了:时间戳 + 32 位(32位全为0),这里记为 tBits

    或运算:同0为0,否则为1

    然后tBits | count,count为32位,所以count只会与tBits的后32位做或运算,由于tBits后32位全为零,000……000 | count = count

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 11月12日
  • 已采纳回答 11月4日
  • 创建了问题 11月4日

悬赏问题

  • ¥15 linux驱动,linux应用,多线程
  • ¥20 我要一个分身加定位两个功能的安卓app
  • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
  • ¥15 IAR程序莫名变量多重定义
  • ¥15 (标签-UDP|关键词-client)
  • ¥15 关于库卡officelite无法与虚拟机通讯的问题
  • ¥15 目标检测项目无法读取视频
  • ¥15 GEO datasets中基因芯片数据仅仅提供了normalized signal如何进行差异分析
  • ¥100 求采集电商背景音乐的方法
  • ¥15 数学建模竞赛求指导帮助