需求:
引用
获取有序随机数字序列,在服务器上全局共享最新的序列.有序随机数字生成规则为 前N位变长递增唯一数字 + (后缀)固定M位随机数字. 例如: 1000 + 1234 -> 10001234; 1001 + 4321 -> 10014321; 1002 + 4567 -> 10024567
测试类:
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class DigitServiceTest implements Runnable {
private DigitNumServiceInterface employeeService;
@Before
public void setUp() throws Exception {
}
@Test
public void digitNumTest() {
for (int i = 0; i < 15; i++)
new Thread(new DigitServiceTest()).start();
}
@After
public void tearDown() throws Exception {
}
public void run() {
employeeService = new EmployeeServiceImpl();
System.out.println(Thread.currentThread() + " empDigit->" + employeeService.getCurrentDigitNum());
}
@Test
public void normalTest() {
employeeService = new EmployeeServiceImpl();
System.out.println(Thread.currentThread() + " empDigit->" + employeeService.getCurrentDigitNum());
}
}
接口:
public interface DigitNumServiceInterface {
/**
* 如果系统中还没有数字帐号记录,以此为起始默认前缀.
* 数字帐号生成规则为前N位唯一数字 + DEFAULT_DIGIT_NUM_SUFFIX_LENGTH位随机数字
*/
Integer DEFAULT_DIGIT_NUM_START = 1000;
/**
* 数字帐号后缀随机数字长度.
*/
Integer DEFAULT_DIGIT_NUM_SUFFIX_LENGTH = 4;
/** 数字帐号初始长度 DEFAULT_DIGIT_NUM_SUFFIX_LENGTH + DEFAULT_DIGIT_NUM_START.length*/
Integer DEFAULT_DIGIT_NUM_MIN_LENGTH = 8;
/** 获取数据库中最新的数字帐号*/
String getLastDigitNumFromDB();
/**获取当前按规则生成好的数字帐号*/
String getCurrentDigitNum();
/** 根据最新的数字帐号获取下一个数字帐号的前缀*/
String getNextDigitNumPrefix(String lastDigitNum);
}
Mock类:
import com.srt.vas.lt.util.StringUtil;
public class EmployeeServiceImpl implements DigitNumServiceInterface {
static String CURRENT_DIGIT_NUM;
/**获取当前按规则生成好的数字帐号,生成失败返回null */
public String getCurrentDigitNum() {
synchronized (DigitNumServiceInterface.DEFAULT_DIGIT_NUM_SUFFIX_LENGTH) {//同步锁
String currentDigitNum = null;
if (CURRENT_DIGIT_NUM == null) {//查询当前系统最新数字帐号
System.out.println("isNull");
currentDigitNum = getLastDigitNumFromDB();
currentDigitNum = getNextDigitNumPrefix(currentDigitNum);
} else {
currentDigitNum = getNextDigitNumPrefix(CURRENT_DIGIT_NUM);
}
if (currentDigitNum != null)
currentDigitNum += StringUtil.randomNumeric(DEFAULT_DIGIT_NUM_SUFFIX_LENGTH);
// currentDigitNum += "0000";
CURRENT_DIGIT_NUM = currentDigitNum;
return CURRENT_DIGIT_NUM;
}
}
public String getNextDigitNumPrefix(String lastDigitNum) {
if (lastDigitNum == null)
return "" + (DEFAULT_DIGIT_NUM_START + 1);
if (lastDigitNum.length() < DEFAULT_DIGIT_NUM_MIN_LENGTH)
return null;
if (lastDigitNum.length() >= DEFAULT_DIGIT_NUM_MIN_LENGTH)
return ""
+ (Integer.parseInt(lastDigitNum.substring(0, lastDigitNum.length()
- DEFAULT_DIGIT_NUM_SUFFIX_LENGTH)) + 1);
return null;
}
public String getLastDigitNumFromDB() {
return "100100000";
}
}
StringUtil:
import java.util.Collection;
import java.util.Map;
import java.util.Random;
import org.apache.commons.lang.RandomStringUtils;//apache common
public class StringUtil{
/**
* 判断字符是否为空,为null,是否由空白字符组成.
* @param str
* @return 为空,null,全部空白字符时返回true,否则false.
*/
public static boolean isEmpty(String str) {
return str == null || str.matches("^\\s*$");
}
/**
* 为null返回true.
* @see StringUtil#isEmpty(String)
* @param l
* @return
*/
public static boolean isEmpty(Long l) {
return l == null;
}
/**
* 为null 返回true.
* @param obj
* @return
*/
public static boolean isEmpty(Object obj) {
return obj == null;
}
@SuppressWarnings("unchecked")
public static boolean isEmpty(Collection c) {
return c == null || c.isEmpty();
}
/**
* 判断是否为空
* @param map
* @return
*/
@SuppressWarnings("unchecked")
public static boolean isEmpty(Map map) {
return map == null || map.isEmpty();
}
/**
* 返回Hql in子句风格的字符串. (Object[, Object])
* Exp: from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )
* from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )
* @param collect
* @return 返回Hql in子句风格的字符串.
*/
public static String getHqlInStyle(Collection<Long> collect) {
Long[] a = collect.toArray(new Long[0]);
if (a.length == 0)
return "";
StringBuilder buf = new StringBuilder();
buf.append('(');
buf.append(a[0]);
for (int i = 1; i < a.length; i++) {
buf.append(", ");
buf.append(a[i]);
}
buf.append(")");
return buf.toString();
}
/**
* 生成指定长度的随机数字.
* @param count
* @return
*/
public static String randomNumeric(int count) {
return RandomStringUtils.randomNumeric(count);
}
/**
* 生成长度为1,值为1-9的随机数字.
* @return
*/
public static String randomNumericBetween1And9() {
return RandomStringUtils.random(1, "123456789");
}
/**
* 生成指定长度的随机数字,第一位不为0.
* @param count
* @return
*/
public static String randomNumericStartWithoutZero(int count) {
return StringUtil.randomNumericBetween1And9() + StringUtil.randomNumeric(count - 1);
}
/**
* 密码为6位随机数字,并且第一位大于0。
* @return
*/
public static String randomNumericPassword() {
return StringUtil.randomNumericBetween1And9() + StringUtil.randomNumeric(5);
}
}
分享到:
相关推荐
用java实现多线程并发中的读者与写者问题,能够实现多线程对临界资源的同步有序访问。 具体实现为: 给定一个队列A[1-10][1-100000]、元素编号1-10,其中每个元素包含10万个随机数。创建若干个线程,各循环100次;...
Java多线程有序读取同一个文件...本文详细介绍了Java多线程有序读取同一个文件的实现方法,包括多线程的实现、文件读取、同步机制等技术。这种技术可以应用于许多实际场景,例如大数据处理、分布式系统、云计算等领域。
在本实验中,我们主要探讨了Java多线程的同步机制以及其在并发编程中的应用。实验目的是理解和掌握并行/并发、同步/异步的概念,并通过实现一个模拟银行账户的程序来具体应用这些概念。 首先,理解并行/并发是关键...
实验使用了Microsoft Visual C++ 6.0,设置为Debug Multithreaded模式,以支持多线程同步测试。 在原始的未同步代码中,两个并发线程(t1和t2)各自读取账户余额,然后随机产生一个数r进行转账。由于线程调度的不确定...
Java多线程程序设计是Java开发中的重要组成部分,它允许程序在同一...总之,Java多线程设计涉及面广泛,包括线程创建、同步、通信、异常处理等多个方面。熟练掌握这些知识对于编写高效、安全的多线程Java程序至关重要。
在这个场景中,我们利用Java多线程来模拟扑克牌的随机分配过程,旨在理解和实践并发编程的基本概念。我们将讨论如何创建线程、同步机制以及随机数生成,以实现公平且有序地将一副扑克牌分配给四位玩家。 首先,我们...
在Java编程中,多线程技术常常用于模拟现实世界中的并发场景,比如模拟排队叫号系统。这个系统可以通过创建多个线程来代表等待服务的客户,一个线程代表叫号服务,通过队列数据结构来有序地管理这些线程。下面我们将...
### 秒杀多线程:深入理解PV操作与多线程同步 在计算机科学领域,尤其是在操作系统和多线程编程中,同步与互斥是确保数据一致性和避免竞态条件的关键概念。**PV操作**,作为实现这些目标的重要工具,自1962年由荷兰...
《用多线程同步方法解决哲学家就餐问题》 在计算机科学领域,操作系统的设计与实现是至关重要的一环,其中涉及到的并发控制问题尤为引人关注。"哲学家就餐问题"(Dining Philosophers Problem)就是一个经典的并发...
多线程排序的挑战在于正确地同步线程,避免数据竞争和死锁,以及有效地分配工作负载,以最大化并行效率。优化点可能包括更智能的基准选择策略、线程池的使用、以及在小数组情况下切换到非并行模式以减少线程创建的...
总的来说,通过研究"哲学家就餐多线程实例图形版",我们可以学习到如何使用Java进行多线程编程,掌握处理并发控制中的死锁问题,以及如何通过线程同步和通信来保证程序的正确运行。这些知识对于理解和解决实际项目中...
在多线程环境中,如果没有采取同步措施,多个线程可能会同时访问和修改同一数据,这可能导致数据的不一致性和错误。为了解决这个问题,Java提供了多种线程同步机制,如`synchronized`关键字、`Lock`接口等。在示例...
2. **线程同步**:为了防止多线程环境下数据的不一致,Java提供了synchronized关键字,可以保证同一时刻只有一个线程访问同步代码块。此外,还有wait()、notify()和notifyAll()方法用于线程间通信。 3. **线程池**...
在多线程编程中,线程同步是解决并发问题的关键技术之一。当多个线程访问共享资源时,如果没有适当的同步机制,可能会导致数据不一致、竞态条件等问题。线程同步的目的在于确保多个线程能够有序地访问共享资源,避免...
Java的多线程编程是开发高并发应用的关键技术之一,主要涉及到线程的创建、运行、调度、同步以及生命周期管理。下面将详细讲解这些知识点。 1. **线程的创建**: Java提供了两种创建线程的方式: - **实现...
在这篇文章中,我们将深入探讨Java的集合框架和多线程这两个关键主题。 **Java集合框架** Java集合框架是Java SE API的一个重要组成部分,它提供了一种高效管理对象的方式。主要包含接口和类,如List、Set、Queue...
在准备大数据面试的过程中,Java基础是必不可少的一部分,尤其聚焦于集合类、多线程和JVM这三大核心领域。下面将分别对这三个方面进行深入探讨。 **一、Java集合类** Java集合框架是处理对象组的重要工具,它包括...
在单核CPU系统中,多线程是通过时间片轮转的方式让多个线程共享一个CPU核心,从而达到同时执行的效果。在多核CPU系统中,每个核心可以独立执行线程,进一步提高系统的并发能力。Java提供了一套完整的多线程模型,...
在这个“作业6-线程同步实验-哲学家就餐问题”的项目中,我们主要探讨的是多线程编程中的一个经典问题——哲学家就餐问题。这个问题由计算机科学家Edsger Dijkstra提出,旨在模拟五个哲学家在共享资源(筷子)时如何...