Code Bye

多线程处理10万个随机数,并且与数据库的不重复

当生成10条数据的时候大致需要2,3个小时的时间,问一下可以用多线程的方式实现吗?或是效率高一点儿的方式
//生成数量
for (int i = 0; i < count; i++) {
String code = CommonUtil.getRedeemCode(6);//1、生成随机码
//2、去数据库查找生成的体验吗能否有重复的
ExperienceCode ex = experienceCodeDao.findcode(code);//数据量较大,比较耗时
while (ex != null) {
code = CommonUtil.getRedeemCode(6);
ex = experienceCodeDao.findcode(code);
}
experienceCodeDao.save(exper);//3.保存数据库
}
解决方案

5

引用:

为啥不用UUID

这个是一个。另一个可以考虑使用CAS,就是不查询直接保存。保存的时候检查一下key能否存在。有点乐观锁的意思

5

引用:

相当于一种优惠码,UUID格式不对,并且要与数据库不重复,CAS还没有了解过,

CAS 不是具体的技术和语言无关。compare and set 本人的思路是从sql层面解决这个问题减少数据库操作

10

可以多线程,前提你写的获取随机数的程式没问题,另外应该全部生成好之后保存数据库,步骤2没必要,数据库设置唯一键,等全部线程都结束之后在保存数据库,保存失败的跳过继续执行,失败数量重新生成。
你也可以先不用多线程,把步骤2去掉,看看速度会不会比较快,感觉是你数据库这块没写好。

5

1、你生产的随机数,大于数据库中的最大值就解决了与数据库不重复,并且不查询数据库的问题!
2、采用多线程生成随机数,可以指定每个线程生成随机数的区间,这样就进一步减小冲突的几率
3、采用一个HashSet保存生成过的随机数,每次生成随机数后,都往HashSet插入,假如add返回false,说明重复,重新生成

5

Well if the running time of 83 billion years does not scare you, think that you will also need to store the generated GUIDs somewhere to check if you have a duplicate; storing 2^128 16-byte numbers would only require you to allocate 4951760157141521099596496896 terabytes of RAM upfront, so imagining you have a computer which could fit all that and that you somehow find a place to buy terabyte DIMMs at 10 grams each, combined they will weigh more than 8 Earth masses, so you can seriously shift it off the current orbit, before you even press “Run”. Think twice!

10

本人尝试使用PROCEDURE来实现相同功能,发现还是可行的.10万测试用时90秒左右.只需在优惠码这个字段建唯一索引.
下面是测试代码.
CREATE TABLE t_b (
   id int(11) NOT NULL AUTO_INCREMENT,
   qx varchar(6) DEFAULT NULL,
   PRIMARY KEY (id),
   UNIQUE KEY ui_qx (qx)
 )
CREATE DEFINER=`root`@`localhost` PROCEDURE `create_round`(in total int)
BEGIN
declare base_string varchar(100);
declare tcode varchar(6);
declare outer_index, inner_index, _err int default 0;
declare continue handler for 1062 set _err = 1;
set base_string:= "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
while outer_index < total do
	#生产6位随机数
    set inner_index = 0;
    set tcode = "";
	while inner_index < 6 do
		set tcode = concat(tcode, substr(base_string, ROUND(RAND()*62),1));
	set inner_index = inner_index + 1;
	end while;
	#插库,重复数据不计数.
	insert into t_b(qx) values(tcode);
    if _err = 1 then
		set _err = 0;
	else
		set outer_index = outer_index + 1;
	end if;
end while;
END
call create_round(100000);

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明多线程处理10万个随机数,并且与数据库的不重复