所用到的并发编程库

import java.util.concurrent.atomic.AtomicInteger;

import java.util.concurrent.locks.ReentrantReadWriteLock;

package com.league.idgenerate;

/**

*

* ID生成器接口, 用于生成全局唯一的ID流水号

*

* @author Ivan.Ma

*/

public interface IdGenerator {

/**

* 生成下一个不重复的流水号

* @return

*/

String next();

}

package com.league.idgenerate;

/**

* ID生成器的配置接口

* @author Ivan.Ma

*/

public interface IdGeneratorConfig {

/**

* 获取分隔符

* @return

*/

String getSplitString();

/**

* 获取初始值

* @return

*/

int getInitial();

/**

* 获取ID前缀

* @return

*/

String getPrefix();

/**

* 获取滚动间隔, 单位: 秒

* @return

*/

int getRollingInterval();

}

package com.league.idgenerate;

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;

import java.util.concurrent.atomic.AtomicInteger;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**

* 默认的ID生成器, 采用前缀+时间+原子数的形式实现

* 建议相同的配置采用同一个实例

* @see IdGeneratorConfig

* @author Ivan.Ma

*/

public class DefaultIdGenerator implements IdGenerator, Runnable{

private String time;

private AtomicInteger value;

private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

private IdGeneratorConfig config;

private Thread thread;

private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

public DefaultIdGenerator(){

config = new DefaultIdGeneratorConfig();

time = LocalDateTime.now().format(FORMATTER);

value = new AtomicInteger(config.getInitial());

thread = new Thread(this);

thread.setDaemon(true);

thread.start();

}

public DefaultIdGenerator(IdGeneratorConfig config){

this.config = config;

time = LocalDateTime.now().format(FORMATTER);

value = new AtomicInteger(config.getInitial());

thread = new Thread(this);

thread.setDaemon(true);

thread.start();

}

@Override

public String next() {

lock.readLock().lock();

StringBuffer sb = new StringBuffer(config.getPrefix()).append(config.getSplitString()).append(time).append(config.getSplitString()).append(value.getAndIncrement());

lock.readLock().unlock();

return sb.toString();

}

@Override

public void run() {

while (true){

try {

Thread.sleep(1000 * config.getRollingInterval());

} catch (InterruptedException e) {

e.printStackTrace();

}

String now = LocalDateTime.now().format(FORMATTER);

if (!now.equals(time)){

lock.writeLock().lock();

time = now;

value.set(config.getInitial());

lock.writeLock().unlock();

}

}

}

}

package com.league.idgenerate;

public class DefaultIdGeneratorConfig implements IdGeneratorConfig{

@Override

public String getSplitString() {

return "";

}

@Override

public int getInitial() {

return 1;

}

@Override

public String getPrefix() {

return "";

}

@Override

public int getRollingInterval() {

return 1;

}

}

测试类, 该类主要演示如何使用及相关测试功能代码,如下:

package com.league.idgenerate;

import java.util.Collections;

import java.util.HashSet;

import java.util.Set;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import org.junit.Test;

/**

* 用法说明

* @author Ivan.Ma

*/

public class TestStandaloneIdGenerator {

@Test

public void test1(){

IdGenerator idGenerator = new DefaultIdGenerator();

System.out.println("--------简单测试------------------");

for (int i=0; i<100; i++){

System.out.println(idGenerator.next());

}

}

@Test

public void test2(){

IdGenerator idGenerator = new DefaultIdGenerator();

//多线程测试

System.out.println("--------多线程测试不重复------------------");

Set idSet = Collections.synchronizedSet(new HashSet<>());

ExecutorService es = Executors.newFixedThreadPool(100);

for (int i=0; i<2000000; i++){

es.submit(() -> {

String val = idGenerator.next();

if (idSet.contains(val)){

System.out.println("重复了: " + val);

}else{

idSet.add(val);

}

});

}

es.shutdown();

System.out.println("启用顺序关闭");

while(true){

if(es.isTerminated()){

System.out.println("所有的子线程都结束了!");

break;

}

try {

System.out.println("子线程的任务还没运行完");

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("共生成: " + idSet.size() + "个");

}

@Test

public void test3(){

//测试单机性能

System.out.println("--------测试单线程性能------------------");

IdGenerator idGenerator2 = new DefaultIdGenerator();

long t1 = System.currentTimeMillis();

int total = 10000000;

for (int i=0; i

idGenerator2.next();

}

System.out.println("单线程生成" + total + "个ID共耗时: " + (System.currentTimeMillis() - t1) + "ms");

}

//500个线程并发, 每个线程获取10000个ID

@Test

public void test4(){

//测试多线程性能

System.out.println("--------测试多线程性能------------------");

ExecutorService es1 = Executors.newFixedThreadPool(500);

IdGenerator idGenerator3 = new DefaultIdGenerator();

long t1 = System.currentTimeMillis();

for (int i=0; i<500; i++){

es1.submit(() -> {

int count = 0;

while (count < 10000){

idGenerator3.next();

count++;

}

});

}

es1.shutdown();

System.out.println("启用顺序关闭");

while(true){

if(es1.isTerminated()){

System.out.println("所有的子线程都结束了!");

break;

}

try {

System.out.println("子线程的任务还没运行完");

Thread.sleep(200);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("500线程,每个线程生成10000个序列号.共耗时: " + (System.currentTimeMillis() - t1) + " ms");

}

@Test

public void test5(){

System.out.println("--------测试生成的ID是否有时间滚动----------");

IdGenerator idGenerator = new DefaultIdGenerator();

for (int i=0; i<20; i++){

String id = idGenerator.next();

System.out.println(id);

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

@Test

public void test6(){

System.out.println("--------ID生成器的特殊设置相关----------");

IdGeneratorConfig config = new DefaultIdGeneratorConfig() {

@Override

public String getSplitString() {

return "-";

}

@Override

public int getInitial() {

return 1000000;

}

@Override

public String getPrefix() {

return "NODE01";

}

};

IdGenerator idGenerator = new DefaultIdGenerator(config);

for (int i=0; i<20; i++){

String id = idGenerator.next();

System.out.println(id);

try {

Thread.sleep(1000 * 1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

运行结果如下:

--------简单测试------------------

201602031124321

201602031124322

201602031124323

201602031124324

201602031124325

201602031124326

201602031124327

201602031124328

201602031124329

2016020311243210

2016020311243211

2016020311243212

2016020311243213

2016020311243214

2016020311243215

2016020311243216

2016020311243217

2016020311243218

2016020311243219

2016020311243220

2016020311243221

2016020311243222

2016020311243223

2016020311243224

2016020311243225

2016020311243226

2016020311243227

2016020311243228

2016020311243229

2016020311243230

2016020311243231

2016020311243232

2016020311243233

2016020311243234

2016020311243235

2016020311243236

2016020311243237

2016020311243238

2016020311243239

2016020311243240

2016020311243241

2016020311243242

2016020311243243

2016020311243244

2016020311243245

2016020311243246

2016020311243247

2016020311243248

2016020311243249

2016020311243250

2016020311243251

2016020311243252

2016020311243253

2016020311243254

2016020311243255

2016020311243256

2016020311243257

2016020311243258

2016020311243259

2016020311243260

2016020311243261

2016020311243262

2016020311243263

2016020311243264

2016020311243265

2016020311243266

2016020311243267

2016020311243268

2016020311243269

2016020311243270

2016020311243271

2016020311243272

2016020311243273

2016020311243274

2016020311243275

2016020311243276

2016020311243277

2016020311243278

2016020311243279

2016020311243280

2016020311243281

2016020311243282

2016020311243283

2016020311243284

2016020311243285

2016020311243286

2016020311243287

2016020311243288

2016020311243289

2016020311243290

2016020311243291

2016020311243292

2016020311243293

2016020311243294

2016020311243295

2016020311243296

2016020311243297

2016020311243298

2016020311243299

20160203112432100

--------多线程测试不重复------------------

启用顺序关闭

子线程的任务还没运行完

子线程的任务还没运行完

子线程的任务还没运行完

子线程的任务还没运行完

子线程的任务还没运行完

所有的子线程都结束了!

共生成: 2000000个

--------测试单线程性能------------------

单线程生成10000000个ID共耗时: 1972ms

--------测试多线程性能------------------

启用顺序关闭

子线程的任务还没运行完

子线程的任务还没运行完

子线程的任务还没运行完

子线程的任务还没运行完

子线程的任务还没运行完

子线程的任务还没运行完

子线程的任务还没运行完

所有的子线程都结束了!

500线程,每个线程生成10000个序列号.共耗时: 1605 ms

--------测试生成的ID是否有时间滚动----------

201602031124431

201602031124432

201602031124433

201602031124434

201602031124435

201602031124436

201602031124437

201602031124438

201602031124439

2016020311244310

2016020311244311

201602031124441

201602031124442

201602031124443

201602031124444

201602031124445

201602031124446

201602031124447

201602031124448

201602031124449

--------ID生成器的特殊设置相关----------

NODE01-20160203112445-1000000

NODE01-20160203112445-1000001

NODE01-20160203112446-1000000

NODE01-20160203112447-1000000

NODE01-20160203112448-1000000

NODE01-20160203112449-1000000

NODE01-20160203112450-1000000

NODE01-20160203112452-1000000

NODE01-20160203112453-1000000

NODE01-20160203112454-1000000

NODE01-20160203112455-1000000

NODE01-20160203112456-1000000

NODE01-20160203112457-1000000

NODE01-20160203112458-1000000

NODE01-20160203112459-1000000

NODE01-20160203112500-1000000

NODE01-20160203112501-1000000

NODE01-20160203112502-1000000

NODE01-20160203112503-1000000

NODE01-20160203112504-1000000

从该性能来看, 可以使用在高并发的场景, 欢迎大家来拍砖!

java 生成 序列号_Java并发编程-生成唯一序列号相关推荐

  1. java线程池_Java 并发编程 线程池源码实战

    作者 | 马启航 杏仁后端工程师.「我头发还多,你们呢?」 一.概述 笔者在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写 ...

  2. java内存 海子_Java并发编程:从根源上解析volatile关键字的实现

    Java并发编程:volatile关键字解析 1.解析概览 内存模型的相关概念 并发编程中的三个概念 Java内存模型 深入剖析volatile关键字 使用volatile关键字的场景 2.内存模型的 ...

  3. java投票锁_Java并发编程锁之独占公平锁与非公平锁比较

    Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家去排队本着先来 ...

  4. java lock 对象_Java并发编程锁系列之ReentrantLock对象总结

    Java并发编程锁系列之ReentrantLock对象总结 在Java并发编程中,根据不同维度来区分锁的话,锁可以分为十五种.ReentranckLock就是其中的多个分类. 本文主要内容:重入锁理解 ...

  5. java计算时间差_JAVA并发编程三大Bug源头(可见性、原子性、有序性),彻底弄懂...

    原创声明:本文转载自公众号[胖滚猪学编程]​ 某日,胖滚猪写的代码导致了一个生产bug,奋战到凌晨三点依旧没有解决问题.胖滚熊一看,只用了一个volatile就解决了.并告知胖滚猪,这是并发编程导致的 ...

  6. java 延迟初始化_Java并发编程——延迟初始化占位类模式

    --仅作笔记使用,内容多摘自<java并发编程实战> 在并发编程中,如果状态变量仅在单个线程中初始化和使用,自然是线程安全的,但一旦涉及到线程间的数据交互,如何声明一个用于多线程的单例状态 ...

  7. java 线程工厂_Java并发编程:Java的四种线程池的使用,以及自定义线程工厂

    引言 通过前面的文章,我们学习了Executor框架中的核心类ThreadPoolExecutor ,对于线程池的核心调度机制有了一定的了解,并且成功使用ThreadPoolExecutor 创建了线 ...

  8. java executor 异步_Java并发编程11-异步执行框架Executor

    1 Executor框架的简介 1.5后引入的Executor框架的最大优点是把任务的提交和执行解耦.要执行任务的人只需把Task描述清楚,然后提交即可.这个Task是怎么被执行的,被谁执行的,什么时 ...

  9. java volatile 原子性_Java并发编程之验证volatile不能保证原子性

    Java并发编程之验证volatile不能保证原子性 通过系列文章的学习,凯哥已经介绍了volatile的三大特性.1:保证可见性 2:不保证原子性 3:保证顺序.那么怎么来验证可见性呢?本文凯哥(凯 ...

  10. java cas机制_java并发编程中的CAS机制,你理解嘛?

    学习Java并发编程,CAS机制都是一个不得不掌握的知识点.这篇文章主要是从出现的原因再到原理进行一个解析.希望对你有所帮助. 一.为什么需要CAS机制? 为什么需要CAS机制呢?我们先从一个错误现象 ...

最新文章

  1. concurrent.futures模块(进程池线程池)
  2. 机械制造技术学习笔记(七)
  3. 标题 穿越雷区 java_【蓝桥杯】穿越雷区-java语言描述
  4. 6.Spring Cloud Alibaba教程:Sentinel流量防卫兵的介绍与基本使用
  5. 页面缓存js问题解决
  6. 攻防世界 适合做桌面_网络安全工程师教你:如何使用Kali Linux进行渗透测试与攻防实战...
  7. MTK:屏幕模板机制
  8. 华为5500v3多路径linux6,CentOS7 DM-Multipath+HUAWEI OceanStor存储多路径配置
  9. JAVA中如何创建一个二维数组,然后给二维数组赋值!
  10. JavaSE集合练习题
  11. 复习步骤7-获取权限数据CustomRealm提供subject桥梁,集成spring - 数据库获取用户权限角色等信息-shiro加密密码和盐存入数据库
  12. Windows11 0x80190001错误解决
  13. pageoffice
  14. Word目录:【同一篇文档设置多个独立目录】详细过程
  15. 从0开始编写minecraft光影包(0)GLSL,坐标系,光影包结构介绍
  16. 生成和扫描二维码(ZXing库)
  17. 火车票服务端集成总结
  18. html调用头尾html,合并html头尾 - 基础支持 - 用gulp搭建前后分离的开发环�? - KK的小故事...
  19. Oracle数据库应用
  20. Windows 找不到文件 “gpedit.msc” ?解决方法:

热门文章

  1. MATPOWER下载安装教程
  2. matlab 安装matpower,MATPOWER的安装详细教程
  3. 卸载mysql服务命令_完全卸载MySQL服务的方法
  4. python贝叶斯网络预测天气_基于pym的贝叶斯网络条件概率表的生成
  5. 时间序列模型 (六):平稳时间序列模型 :自回归AR 、移动平均 MA 、ARMA 模型
  6. 全局光照算法:IBL
  7. IDEA添加新项目到SVN
  8. 初学3D建模有这80G笔刷简直绝了
  9. ionic app 开发学习
  10. linux如何删除tree命令,误删tree命令如何恢复