有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java即使是同步的方法也会生成相同的UUID

我知道很多人不会相信这一点,但我目前面临的一个问题是,即使生成UUID的方法是同步的,我也会得到相同的UUID

private synchronized String generateUUID() {
        return UUID.randomUUID().toString();
 }

现在,我的应用程序将记录存储在数据库中(并行、多线程),并且可以将此UUID视为唯一密钥的一部分。即使线程之间的时差为1ns,我希望此方法在保留记录之前返回实际生成的唯一字符串

我是否有办法保证这个唯一ID的生成实际上是唯一的


共 (2) 个答案

  1. # 1 楼答案

    免责声明:这是不应该发生的,这个解决方案只是一个黑客让你继续前进,直到你解决了根本的问题

    AtomicInteger hackDigit = new AtomicInteger(0);
    
    private synchronized String generateUUID() {
            return UUID.randomUUID().toString() + hackDigit.getAndIncrement();
    }
    

    编辑:顺便说一下,这是一个很好的方法,可以帮助您排除故障,因为您可以验证该方法是否被多次调用

  2. # 2 楼答案

    我用jdk1测试了以下代码。7.0_76和jdk1。6.0_75:

    public static void main(String[] args) throws InterruptedException {
        final CountDownLatch latch = new CountDownLatch(1);
        int numThreads = 30;
    
        ExecutorService es = Executors.newFixedThreadPool(numThreads);
        for (int i = 0; i < numThreads; i++) {
            es.execute(new Runnable() {
    
                @Override
                public void run() {
                    try {
                        latch.await();
                        System.out.println(Thread.currentThread().getId() + ":  UUID = " + generateUUID());
                    } catch (InterruptedException ex) {
                    }
                }
            });
        }
        latch.countDown();
        es.shutdown();
    }
    
    private static synchronized String generateUUID() {
        return UUID.randomUUID().toString();
    }
    

    我得到了以下结果:

    38:  UUID = 5fd7d56a-42a9-4edc-a114-ccf86bcf1e20
    37:  UUID = be1815fd-3bd4-4761-bcf7-4ad303ee585a
    23:  UUID = 80c1920e-566a-44d7-993c-4ce0807e0aef
    22:  UUID = caba14c7-77fc-4ed5-9063-5c41d6ee43dc
    21:  UUID = a542a0e9-55c3-4a95-8614-86dcb052d337
    24:  UUID = abdb5275-a3c3-4114-aa4e-088d978d4ba1
    25:  UUID = f0ddaa6d-9129-4344-bcf7-499663203270
    26:  UUID = b997ee94-555a-4a26-9c6c-8415ff301b18
    20:  UUID = d9f3b912-251b-45b6-b15b-22f6b1c44d13
    27:  UUID = 54c491c0-e2a6-4eda-988f-d468e7c089d9
    28:  UUID = 7b94ee4e-e450-4d35-ad65-28b0ae394c12
    29:  UUID = 4cea2da0-9815-418c-b6d8-98e40d382ca5
    30:  UUID = 6025824c-2f8c-4d90-9631-2e178c2679cc
    31:  UUID = e743664c-df13-4f56-9f4c-f3e47729d9a7
    15:  UUID = 35f1a715-c5c5-4db1-9ac4-a8ecd33f32d2
    32:  UUID = e6371c34-b6fb-4f83-955d-0a9cc2b464db
    33:  UUID = 8e26bd45-2e0a-47b2-b8ec-4e76aae18174
    14:  UUID = 0b5b1c58-71df-4351-9275-5f192f485700
    13:  UUID = 93bb6308-ca15-4c82-b2e1-10f17e41597a
    34:  UUID = a64770ae-8828-446c-af7a-a327d097871f
    11:  UUID = e45fef37-ab5d-42c4-b786-71f30aee3fa4
    10:  UUID = 1d6938ce-27db-4cad-a191-21cf008671cc
    9:  UUID = 2fa7e5c6-ac7c-4ce8-98fa-b298013aaf52
    35:  UUID = ffda2492-1c43-42ff-baf4-0a122e67e8ac
    36:  UUID = 9e630172-e90a-48f1-8e13-c57c119f7ede
    12:  UUID = 9e378e06-d502-4ce7-94ad-5cc1431801cd
    16:  UUID = bb17f0da-7672-4009-8fad-51050aa6bb69
    17:  UUID = c0dec6ab-324b-466c-a69f-4c667c240dd4
    18:  UUID = 3398dd05-1020-4df4-b365-73083950a5a4
    19:  UUID = 84766676-d7f5-4fae-9765-367bbf4efebe
    

    你在使用哪个JDK?你能用JDK试试这段代码吗?此外,我还测试了有无同步。另外,我做了静态测试,但可以在没有静态测试的情况下进行测试