生成的GUID是重复的,我的Java代码错误吗?

时间:2018-07-13 08:36:03

标签: java guid

根据我在Internet上找到的信息,GUID重复的可能性很小,所以我的代码有问题吗?

public class AccountTaskExecutorTask extends TimerTask {
    private static final Logger logger = Logger.getLogger(AccountTaskExecutorTask.class);
    private TellerDbCore.AccountTask.Builder aTask = null;

    public AccountTaskExecutorTask(TellerDbCore.AccountTask.Builder aTask) {
        this.aTask = aTask;
    }

    public static void schedule(TellerDbCore.AccountTask.Builder aTask) {
        Timer timer = new Timer();
        timer.schedule(new AccountTaskExecutorTask(aTask), 100L);
    }

    @Override
    public void run() {
        try {
            DataBaseStore dataBaseStore = null;
            try {
                dataBaseStore = DbHelper.getTransactableDbStore();
                invest(aTask, dataBaseStore);
                dataBaseStore.commitAndClose();
                dataBaseStore = null;
            } catch (Exception e) {
                logger.error("", e);
                if (dataBaseStore != null) {
                    dataBaseStore.rollbackAndClose();
                    dataBaseStore = null;
                }
            }
        } catch (Exception e) {
            logger.error("", e);
        }
    }


    private static void invest(TellerDbCore.AccountTask.Builder theTask, DataBaseStore dataBaseStore) throws Exception {
            switch (theTask.getTaskStatus()) {
                case TS_READY:
                    List<TellerDbCore.AccountSubTask.Builder> subList = AccountTaskHelper.querySubAtByMtId(theTask.getTaskId(), dataBaseStore);
                    if (subList.size() == 0) {
                        NewMethods.newAccountSubTask(theTask.getTaskId(), GUID.generateGUID().toLowerCase(),
                                theTask.getAccountId(), theTask.getProductType(), theTask.getTaskType(), theTask.getAmount(), dataBaseStore);
                    }
                    UpdateMethods.updateAccountTask(theTask.getTaskId(), null, BtsDbBase.TaskStatus.TS_PROCESSING, dataBaseStore);
                    break;
                case TS_PROCESSING:
                    break;
                case TS_SUCCESSED:
                case TS_FAILED:
                    break;
                default:
                    logger.info( theTask.getTaskStatus());
                    break;
            }
    }
}

在此代码中,GUID是由GUID.generateGUID().toLowerCase()生成的,打包的次数是oscore-2.2.4.jarNewMethods.newAccountSubTask是将数据添加到数据库中。

这是GUID

的代码
package com.opensymphony.util;

import com.opensymphony.module.random.Yarrow;
import java.math.BigInteger;

public final class GUID
{
  private static Yarrow rnd = new Yarrow();

  public static String generateFormattedGUID()
  {
    String guid = generateGUID();

    return guid.substring(0, 8) + '-' + guid.substring(8, 12) + '-' + guid.substring(12, 16) + '-' + guid.substring(16, 20) + '-' + guid.substring(20);
  }

  public static String generateGUID()
  {
    return new BigInteger(165, rnd).toString(36).toUpperCase();
  }
}

1 个答案:

答案 0 :(得分:0)

假设GUID的潜在值的数量为n,这是一个非常大的自然数。我们还假设已经选择的值的数量为k。现在,值重复的概率(p)取决于n和k。 n是一个非常大的自然数,但让我们看一下k的可能值(我正在使用所有可能值都具有大致相同概率的假设):

k == 0

在这种情况下,您将获得第一个GUID,并且不可能获得重复的GUID。 p == 0

k === n

在这种情况下,您已经拥有所有可能的值,并且不可能没有重复的值。 p == 1

0 <= k <= n

在这种情况下,获得新价值的可能性是:

p ==(n-k)/ n

因为我们需要排除已经选择的k个元素。另一方面,获得重复的概率为

p'== k / n

因此,随着k的增加,p减小,而p'增大。注意,前两种情况是该一般情况的特殊情况。现在,解决方案是什么,这样您将不会得到重复的副本?

好吧,您使用的是小写字母,这基本上将可能的值减小到一半。如果避免使用小写字母,则n实际上会翻倍。另外,您可以为新值使用两个串联的guid值,因为它们的字符串长度不同,所以它们永远不会与以前使用的值重复。或者,您可以在gui字符串之前使用id。