在开发中,我们需要生成一些流水号,订单编号,等等一些东西。这个时候需要我们使用锁来控制流水码的唯一。
不啰嗦。直接上代码。另外大家觉得好看有用,给点个赞呗。
import com.mindskip.sdd.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
/**
* 下单
*
* @author 567
*/
@RestController
@RequestMapping(value = "/api/order")
public class OrderController{
/**
* 流水码表,只有四个字段:id,类型,流水码,日期(定时任务,每天24时都会清空这张表)
*/
private SerialNumberService serialNumberService;
/**
* 指针1:记录已有流水号的单号
*/
public static int num = 0;
/**
* 指针2:记录时间每天重新生成流水单号
*/
public static String nowDay = "";
/**
* 锁,多线程/并发下,保障单号生成唯一
*/
private static ReentrantLock lock = new ReentrantLock();
/**
* 机构编码(10位前置字符,不够补零)+yyyyMMdd+ 6位流水号
*
* @return
*/
private String generatorOrderCode() {
//getCurrentUser 为获取用户
String domain ="想要的前置字符";
//不够10位,补0
for (int i = domain.length(); i < 10; i++) {
domain = String.format("%s0", domain);
}
return getNum(serialNumberService, domain).toUpperCase(Locale.ROOT);
}
/**
* 生成订单的流水码
*
* @param code
* @return
*/
private static String getNum(SerialNumberService serialNumberService, String code) {
//指针,最后生成的数
String unique = "";
//上锁
lock.lock();
try {
//现在的日期
String newDay = new SimpleDateFormat("yyyyMMdd").format(new Date());
if (StringUtils.isBlank(nowDay)) {
//nowDay 是第一次启动。给与当天的日期
nowDay = newDay;
}
if (!nowDay.equals(newDay)) {
//记录的天,跟现在的日期不一致。则赋值num重新生成编号。
//用于上线后,一直运行不曾中断,第二天申请开班的情况
num = 0;
nowDay = newDay;
}
//5位流水号
if (num == 0) {
//当天第一份流水单号
//查询当天最大id的流水单号。
//如果大家觉得ReentrantLock锁不保险,可以尝试数据库加锁
String k = serialNumberService.selectNowDayMaxId();
if (k == null) {
unique = nowDay + "000001";
} else {
//从k的流水单号里,截取字符,获取单号。其实使用id可是可以的。
num = Integer.parseInt(k.substring(19, 24));
unique = unique();
}
} else {
unique = unique();
}
//已有流水单+1
num++;
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
}
return code + unique;
}
private static String unique() {
//当天最后的订单流水号累加1
String nums = String.valueOf(num + 1);
//设定具体流水为两位数,单数则补齐前面的0
StringBuilder sb = new StringBuilder(nums);
for (int i = nums.length(); i < 6; i++) {
sb.insert(0, "0");
}
return nowDay + sb;
}
}
对了,多谢这位的博客:https://blog.csdn.net/weixin_38256539/article/details/125393024