我有一个物品对象工厂,他引用了所有的物品对象,一个玩家可以持有多个相同的物品。为了唯一标识一个物品,这里我采用运行时变量。这个唯一标识只是针对于物品来说,假如是另一个对象,则可以和物品的运行时id相同,所以我觉得这里不需要采用UUID我是这么做的
public synchronized String getRunTimeId() {
if(runTimeId != Long.MAX_VALUE) {
runTimeId += 1;
} else {
runTimeId = 0;
}
return runTimeId + "";
}
但是我担心一件事情,就是对象工厂中的对象太多,有没有可以同时存在两个runTimeId=0的对象。同样还有一件事,对于匿名登录用户通常用怎样的运行时变量来唯一标识

解决方案 »

  1.   


    Long runTimeId = 0l, runTimeId2 = 0l;    public synchronized String getRunTimeId()
        {
            Long uniqueId = (runTimeId == Long.MAX_VALUE) ? --runTimeId2: --runTimeId;        return uniqueId.toString();
        }
    如果这样的话这个唯一标识如果到最小值就又不行了 
    你要确保你的唯一ID总数是Long的长度范围的2倍之内才行!
      

  2.   

    如果你不需要保存数据到数据库中的话,就像你那样用静态变量。如果有数据库,可以考虑直接用数据库的 sequence 之类的帮你记录。只要是你生成的唯一的编号,就随便你想办法,如果匿名登录的是 HTTP session 就用 Web 服务器提供的 session id 就可以了,如果是自己的管理的 TCP 会话,那还是像之前说的一样,自己随便用什么静态变量或数据库 sequence 搞定它。
      

  3.   

    可以用系统日期在链接上你的静态变量的值。
    如:System.currentTimeMillis() + 静态变量的值,字符串拼接1285059333671 + 9 -->12850593336719
      

  4.   

    oracle sequence 不会出问题,Oracle Sequence 即使在事务失败时也不会回滚,放心使用。用 Sequence 的话,一般不会用一个查一个,这样效率太低了。可以这样:获取 Oracle Sequence 值乘以 50,那个 1 个序列就可以使用 50 次了,用完了再去取 sequence 值,这时值为 2,乘以 50 的话又可以用 50 次了。这种做法是 J2EE 设计模式之一——主键批量生成器。静态变量肯定不行,除非你的应用从来不停机!另外,可以使用文件读写锁,使用文件作为序列暂存,以替代 Sequence,但这样做法很麻烦,不推荐。
      

  5.   

    我生成的这个运行时变量并不存储到数据库,只是为了在运行时标识物品。
    物品的存储我是以集合的形式存在用户和场景中,不会单独存储。
    所以id的生成我用不到数据库,有用Java实现的方式吗?
    系统重启后,创建原来的物品时会重新分配一个运行时id给这个物品。我只要求在运行环境中没有物品的运行时标识是重复的
      

  6.   

    楼主的方法已经很好了,看了上面几位朋友的回复,我反倒迷惑了。楼主原来的做法有什么问题吗?说实话没看懂楼主那句话。我觉得“匿名用户”跟“普通登录用户”的标识方法是一样的,都会有一个“session id”(也许是通过 cookie,也许是 rewrite url),不同的只是这个 session id 对应的 Session 对象里面保存的东西不同。■□■□■□■□■□■□■□■
    □             □
    ■  忍以明志 勤以致远  ■
    □             □
    ■□■□■□■□■□■□■□■
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  7.   

    to 12楼运行时中,long从0一直累加到MaxValue,然后又会变成0。
    当long再次变成0时,以前的runTimerId=0的物品还没有被工厂释放,这个时候就可能出现两个相同的运行时id,不过我不知道虚拟机能支持Long.MaxValue个对象吗?如果不支持的话,我的担忧就是多余的
      

  8.   

    哦,楼主是担心这个呀,明白了。Java 里 Long 值的长度是 8 个字节,它能表示的数量范围非常大,以前我从没考虑过自己的程序里会有它表示不了的数量值,所以从来没考虑过越界问题。对于你要表示的“物品”,如果数量要超过这个范围,估计内存早爆了。就算你的物品可以“销毁/新建”,也可以大概估算一下它的频率,按常理估计应该是足够用的。■□■□■□■□■□■□■□■
    □             □
    ■  忍以明志 勤以致远  ■
    □             □
    ■□■□■□■□■□■□■□■
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  9.   

    刚刚简单估算了一下,就算你每秒钟创建 2 亿个物品,这个 id 也够用几十年的 :)■□■□■□■□■□■□■□■
    □             □
    ■  忍以明志 勤以致远  ■
    □             □
    ■□■□■□■□■□■□■□■
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)