这是一个短暂的应用程序,没有数据库,只在内存中保留原始的映射->缩短。如果我有下面的scala方法,它每次都会被调用,以生成一个值(然后将其用作一个缩短的URL),然后保存在一个Map(originalUrl->shortenUrl )中。从42亿(Integer.MAX_VALUE)可能性中选择,参考36。如果在多线程环境中调用,生成唯一的缩短URL值的方法有什么缺点吗?
def randomUrl: String = {
Integer.toString(new Random().nextInt(Integer.MAX_VALUE), 36)
}发布于 2014-03-14 02:26:31
你应该不会有任何问题。下面的一行代码是Scala随机构造函数。
def this() = this(new java.util.Random())默认构造函数的OpenJDK源代码确实使用了System.nanoTime(),但它不仅仅使用时间。它使用一个AtomicLong并调用compareAndSet (一个原子操作)来设置一个新值。This atomic operation is thread-safe.如果该值已由另一个线程设置,它将重试另一个AtomicLong值以使您的种子唯一。
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}发布于 2014-03-14 00:53:30
对于只有31位的信息,不唯一性可能会是一个问题。您将期望在仅生成大约64k个URL之后第一次发生冲突。使用更多的位。而且你不能确保你的种子在这种方法下是不同的,所以你最好创建一个随机数源并分享它。
java.util.Random是线程安全的,而Scala只是转发给Java实现,所以即使不是每次调用都创建一个新的Random,在线程安全方面也应该没问题。
https://stackoverflow.com/questions/22384696
复制相似问题