UUID组成部分
1+分片标识符+年月日+递增数字
其中递增数字,长度不够前面补0
实现
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;
public class UUIDGenerator {
// 分片号,占4位
private static String slotId;
// 是否调用init()方法进行初始化
private static boolean inited = false;
private static int date;
private static AtomicLong incre = new AtomicLong(1);
private static final String DataFormat = "yyMMdd";
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>();
private static DateFormat getDateFormat() {
DateFormat df = threadLocal.get();
if (df == null) {
df = new SimpleDateFormat(DataFormat);
threadLocal.set(df);
}
return df;
}
/**
* 按指定格式对Date所持有的时间进行格式化
* @param date
* @return
*/
private static int format(Date date) {
return Integer.valueOf(getDateFormat().format(date));
}
/**
* 指定时间戳所在日期的0点时间戳
* @param millis
* @return
*/
private static long zeroTime(long millis) {
Calendar calendar = Calendar.getInstance();
// TimeZone curTimeZone = TimeZone.getTimeZone("GMT+8");
// Calendar calendar = Calendar.getInstance(curTimeZone);
calendar.setTimeInMillis(millis);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTimeInMillis();
}
/**
* 在使用前调初始化
*
* @param slotId
*/
public static void init(int slotId) {
if (inited) {
return;
}
if (slotId >= 1000) {
throw new RuntimeException("Slot ID must be smaller than 10000");
}
UUIDGenerator.slotId = String.format("%03d", slotId);
inited = true;
}
/**
* 生成UUID
* @return
*/
public static long generate() {
if (!inited) {
throw new RuntimeException("The init() method must be called first");
}
int currDate = format(new Date());
if (currDate != date) {
synchronized (UUIDGenerator.class) {
if (currDate != date) {
//自增偏移量,初始值设置为当日的秒数,防止因重启或其他原因造成生成的ID重复
long offset = 1+(System.currentTimeMillis() - zeroTime(System.currentTimeMillis()))/1000;
System.out.println("offset: "+offset);
incre.set(offset);
date = currDate;
}
}
}
String uuid = String.format("1%s%d%09d", slotId, date, incre.getAndIncrement());
return Long.valueOf(uuid);
}
public static void main(String[] args) throws InterruptedException {
UUIDGenerator.init(5);
int jmax = 1000;
CountDownLatch countDownLatch = new CountDownLatch(10);
HashSet<Long> uuids = new HashSet<>();
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < jmax; j++) {
long uuid = UUIDGenerator.generate();
System.out.println(uuid);
uuids.add(uuid);
}
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
if(uuids.size() != jmax*10) {
System.out.println("UUID generate error ...... !!!");
}else {
System.out.println("UUID generate success!!!");
}
}
}
总结
每日可保存上亿的UUID生成,足够项目使用。
网友评论