如何在Java中获取与uint32_t对应的唯一值?
Posted
技术标签:
【中文标题】如何在Java中获取与uint32_t对应的唯一值?【英文标题】:How to get a unique value in Java that corresponds to uint32_t? 【发布时间】:2017-01-22 23:48:33 【问题描述】:我必须在 Java 中生成一个唯一编号(对于运行代码的我的机器),以便在 C++ 中它可以对应于uint32_t
。一般来说,其他 C++ 程序应该能够正确地读取这个唯一编号为uint32_t
。我在一个字节数组中发送这个信息,其他 C++ 程序正在反序列化它以获得这个数字。到目前为止,我无法在 C++ 程序中更改此数字的数据类型。
private static final AtomicInteger clientId = new AtomicInteger(0);
// will be called many time when the program is running after initialization
public static int getClientId()
int counter = clientId.incrementAndGet();
return counter == Integer.MAX_VALUE ? 0 : counter;
// called only once at startup
public static void setClientId(final int counter)
clientId.addAndGet(counter == Integer.MAX_VALUE ? 0 : counter);
所以我想出了上面的代码。我的setClientId
方法在应用程序启动(初始化阶段)期间只会被调用一次:
0
传递给setClientId
方法。
如果这台机器已经在运行代码但我们重新启动了服务器,那么我将在数据库中查找这台机器最后保存的值是什么(因为我们也每隔几分钟将这个值保存在 db 中)然后我将该值传递给 setClientId
方法。
然后当我的程序运行时(在初始化之后),它会继续调用getClientId
方法来给我实际唯一的clientId。
这是为我的机器生成唯一 ID 的正确方法,对于 C++ 程序来说,这将是 uint32_t
?我还确保如果该值达到Integer.MAX_VALUE
,则将其设置为 0 并重新开始。我必须这样做吗?或者我也可以为此 uint32_t
取负值?
基本上,我想为我的机器生成一个唯一编号,该编号应始终对应于uint32_t
。如果机器是新机器,我们可以从数字 0 开始(bcoz 当我们在数据库中查找这台机器的值时,不会有任何值,所以我们将从 0 开始)但是如果机器之前已经运行过这段代码,然后从数据库中最后保存的值开始。
【问题讨论】:
Java 整数是有符号的,如果你想要完整的范围,你也必须取负值。 那么uint32_t
也能理解负整数值吗?请原谅我在这里对 C++ 的无知。
只有当您期望生成超过 2,147,483,647 个唯一 ID 时才会出现问题。但是,如果您将 Java 签名的 int
(可能为负数)序列化为 4 个字节,并将 C++ 程序中的这 4 个字节反序列化为 uint32_t
,C++ 程序会将负 Java 整数视为 2147483648 到4294967295.
我明白了。然后最好只发送正整数值,以便它只能反序列化正整数值。对于长时间运行代码的机器,它有可能超过2,147,483,647 unique ID's
,一旦达到该限制,我就会再次将其重置回0。
@david 好主意。另一种方法是在 Java 中使用 long
并手动将内容转换为 C 期望的格式(仅发送低 32 位)。
【参考方案1】:
我必须这样做吗?或者我也可以为这个 uint32_t 取负值?
不,您不必这样做,您也可以取负值。如果您将 Java 整数逐位传递给 C++,即使 Java 变量超过最大值并变为负数,C++ 中的 unit32_t 也会继续增加。这是 2 的补码有符号整数的好处,Java 用它来表示整数值。
这是一个 4 位示例,说明正在发生的事情:
Bits Unsigned Signed
0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 -8
1001 9 -7
1010 10 -6
1011 11 -5
1100 12 -4
1101 13 -3
1110 14 -2
1111 15 -1
另请参阅此答案:What happens when you increment an integer beyond its max value。
【讨论】:
我明白了.. 那么我的 get 和 set 方法看起来如何呢?我想我不再需要那个最大值检查了。 恕我直言,最大值检查只是将计数器的值限制为非负数。如果你放弃检查,变量无论如何都会环绕(只是更慢)。 另一个问题是,当你环绕时,你会得到重复(是的,这是一个很长的序列,但仍然......)以上是关于如何在Java中获取与uint32_t对应的唯一值?的主要内容,如果未能解决你的问题,请参考以下文章
使用多个 uint32_t 整数生成 uint64_t 哈希键