多线程是java中唯一id的线程安全代码
我有一个简单的代码,希望生成具有唯一id的对象
public class Test {
private static long counter = 0;
private long id;
private Test() {
// Don't worry about overflow
id = counter++;
}
// Will this method always Test Object with unique id?
public static Test getTest() {
return new Test();
}
public long getId() {
return id;
}
}
想知道多个线程是否调用了getTest方法所有testobject都有唯一的id吗
# 1 楼答案
如果要锁定类级变量(不是实例变量,因为实例变量不需要同步。一次只能有一个线程创建对象),也可以在构造函数中使用synchronize block。 所以你也可以把它作为构造器来尝试
# 2 楼答案
不,生成唯一ID不是线程安全的。对象很可能会收到非唯一ID。可以使用AtomicInteger/AtomicLong来实现这一点(即
private static AtomicLong counter = (new AtomicLong())
),然后在Test
的构造函数中counter.getAndIncrement()
它不是线程安全的原因是每个处理器/内核都有自己的寄存器集,如果不同步,变量在不同的处理器/内核中可能有不一致的副本。即使在单处理器系统上,抢占式多线程也会带来同样的问题。在非抢占式线程系统中不需要同步
# 3 楼答案
这不是线程安全的,因为两个线程可以同时执行计数器+,并且可能会得到意外的结果
您应该使用AtomicInteger: