如何在 Java 中获取对应于 uint32_t 的唯一值?
How to get a unique value in Java that corresponds to uint32_t?
我必须在 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
方法。
- 如果这台机器已经是 运行 代码但我们重新启动了服务器,那么我将在数据库中查找这台机器最后保存的值是什么(因为我们也在数据库中保存了这个值几分钟),然后我将该值传递给
setClientId
方法。
然后当我的程序是 运行(初始化后)时,它将继续调用 getClientId
方法来给我实际的唯一 clientId。
这是为我的机器生成唯一 ID 的正确方法吗?对于 C++ 程序,它是 uint32_t
?我还要确保如果该值达到 Integer.MAX_VALUE
,则将其设置为 0 并重新开始。我必须这样做吗?或者我也可以为此 uint32_t
?
取负值
基本上,我想为我的机器生成一个唯一编号,该编号应始终对应于 uint32_t
。如果机器是一台新机器,我们可以从数字 0 开始(因为当我们在数据库中查找这台机器的值时,不会有任何值所以我们将从 0 开始)但是如果机器已经 运行 这段代码之前,然后从数据库中最后保存的值开始。
Do I have to do this? Or I can take negative values as well for this uint32_t?
不,你不必,你也可以取负值。如果将 Java 整数传递给 C++ bit-by-bit,即使 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。
我必须在 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
方法。 - 如果这台机器已经是 运行 代码但我们重新启动了服务器,那么我将在数据库中查找这台机器最后保存的值是什么(因为我们也在数据库中保存了这个值几分钟),然后我将该值传递给
setClientId
方法。
然后当我的程序是 运行(初始化后)时,它将继续调用 getClientId
方法来给我实际的唯一 clientId。
这是为我的机器生成唯一 ID 的正确方法吗?对于 C++ 程序,它是 uint32_t
?我还要确保如果该值达到 Integer.MAX_VALUE
,则将其设置为 0 并重新开始。我必须这样做吗?或者我也可以为此 uint32_t
?
基本上,我想为我的机器生成一个唯一编号,该编号应始终对应于 uint32_t
。如果机器是一台新机器,我们可以从数字 0 开始(因为当我们在数据库中查找这台机器的值时,不会有任何值所以我们将从 0 开始)但是如果机器已经 运行 这段代码之前,然后从数据库中最后保存的值开始。
Do I have to do this? Or I can take negative values as well for this uint32_t?
不,你不必,你也可以取负值。如果将 Java 整数传递给 C++ bit-by-bit,即使 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。