分布式锁一般有三种实现方式:
- 数据库乐观锁;
- 基于Redis的分布式锁;
- 基于ZooKeeper的分布式锁
单体应用上根据时间戳+num++ 实现唯一ID
首先我们定义一个接口
public interface IGenerateGlobalId {
public String idGenerator();
}
实现两个子类,一个是使用synchronized修饰,一个不使用
public class SequenceLockGenerateGlobalIdImpl implements IGenerateGlobalId{
private static int num;
@Override
public synchronized String idGenerator() {
SimpleDateFormat data = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String format = data.format(new Date())+"-"+ num++;
return format;
}
}
public class SequenceUnLockGenerateGlobalIdImpl implements IGenerateGlobalId{
private static int num;
@Override
public String idGenerator() {
SimpleDateFormat data = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String format = data.format(new Date())+"-"+ num++;
return format;
}
}
现在通过模拟,在同一时刻,有多个线程过来同时请求获取ID
public class JvmTestTask implements Runnable{
private IGenerateGlobalId iGenerateGlobalId;
private CountDownLatch latch;
public JvmTestTask(IGenerateGlobalId iGenerateGlobalId, CountDownLatch latch) {
this.iGenerateGlobalId = iGenerateGlobalId;
this.latch = latch;
}
@Override
public void run() {
try {
latch.await();
String idGenerator = JvmLockUtil.idGenerator(iGenerateGlobalId);
System.out.printf("线程名称:%s ID:%s \r\n", Thread.currentThread().getName(),idGenerator);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SequenceLockGenerateGlobalIdImpl entity = new SequenceLockGenerateGlobalIdImpl();
ExecutorService pool = Executors.newCachedThreadPool();
final CountDownLatch latch = new CountDownLatch(1);
for(int i=0;i<10;i++) {
pool.execute(new JvmTestTask(entity,latch));
}
latch.countDown();
pool.shutdown();
}
}