`
QiaoDuanni
  • 浏览: 136909 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

多线程获取有序随机数字(同步)

    博客分类:
  • java
阅读更多
需求:
引用
获取有序随机数字序列,在服务器上全局共享最新的序列.有序随机数字生成规则为 前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);
	}
	
}
0
0
分享到:
评论

相关推荐

    java实现多线程间的同步与互斥(读者写者问题)

    用java实现多线程并发中的读者与写者问题,能够实现多线程对临界资源的同步有序访问。 具体实现为: 给定一个队列A[1-10][1-100000]、元素编号1-10,其中每个元素包含10万个随机数。创建若干个线程,各循环100次;...

    java多线程有序读取同一个文件

    Java多线程有序读取同一个文件...本文详细介绍了Java多线程有序读取同一个文件的实现方法,包括多线程的实现、文件读取、同步机制等技术。这种技术可以应用于许多实际场景,例如大数据处理、分布式系统、云计算等领域。

    使用Java多线程的同步机制编写应用程序.docx

    在本实验中,我们主要探讨了Java多线程的同步机制以及其在并发编程中的应用。实验目的是理解和掌握并行/并发、同步/异步的概念,并通过实现一个模拟银行账户的程序来具体应用这些概念。 首先,理解并行/并发是关键...

    操作系统线程同步机制

    实验使用了Microsoft Visual C++ 6.0,设置为Debug Multithreaded模式,以支持多线程同步测试。 在原始的未同步代码中,两个并发线程(t1和t2)各自读取账户余额,然后随机产生一个数r进行转账。由于线程调度的不确定...

    我总结的Java多线程程序设计

    Java多线程程序设计是Java开发中的重要组成部分,它允许程序在同一...总之,Java多线程设计涉及面广泛,包括线程创建、同步、通信、异常处理等多个方面。熟练掌握这些知识对于编写高效、安全的多线程Java程序至关重要。

    java多线程模拟扑克牌的发放

    在这个场景中,我们利用Java多线程来模拟扑克牌的随机分配过程,旨在理解和实践并发编程的基本概念。我们将讨论如何创建线程、同步机制以及随机数生成,以实现公平且有序地将一副扑克牌分配给四位玩家。 首先,我们...

    java多线程模拟队列实现排队叫号

    在Java编程中,多线程技术常常用于模拟现实世界中的并发场景,比如模拟排队叫号系统。这个系统可以通过创建多个线程来代表等待服务的客户,一个线程代表叫号服务,通过队列数据结构来有序地管理这些线程。下面我们将...

    秒杀多线程

    ### 秒杀多线程:深入理解PV操作与多线程同步 在计算机科学领域,尤其是在操作系统和多线程编程中,同步与互斥是确保数据一致性和避免竞态条件的关键概念。**PV操作**,作为实现这些目标的重要工具,自1962年由荷兰...

    用多线程同步方法解决哲学家就餐问题

    《用多线程同步方法解决哲学家就餐问题》 在计算机科学领域,操作系统的设计与实现是至关重要的一环,其中涉及到的并发控制问题尤为引人关注。"哲学家就餐问题"(Dining Philosophers Problem)就是一个经典的并发...

    c.rar_多线程排序_多线程排序c_快速排序

    多线程排序的挑战在于正确地同步线程,避免数据竞争和死锁,以及有效地分配工作负载,以最大化并行效率。优化点可能包括更智能的基准选择策略、线程池的使用、以及在小数组情况下切换到非并行模式以减少线程创建的...

    哲学家就餐多线程实例图形版

    总的来说,通过研究"哲学家就餐多线程实例图形版",我们可以学习到如何使用Java进行多线程编程,掌握处理并发控制中的死锁问题,以及如何通过线程同步和通信来保证程序的正确运行。这些知识对于理解和解决实际项目中...

    Thread类&java多线程(代码篇).pdf

    在多线程环境中,如果没有采取同步措施,多个线程可能会同时访问和修改同一数据,这可能导致数据的不一致性和错误。为了解决这个问题,Java提供了多种线程同步机制,如`synchronized`关键字、`Lock`接口等。在示例...

    JAVA集合、多线程

    2. **线程同步**:为了防止多线程环境下数据的不一致,Java提供了synchronized关键字,可以保证同一时刻只有一个线程访问同步代码块。此外,还有wait()、notify()和notifyAll()方法用于线程间通信。 3. **线程池**...

    线程同步方法

    在多线程编程中,线程同步是解决并发问题的关键技术之一。当多个线程访问共享资源时,如果没有适当的同步机制,可能会导致数据不一致、竞态条件等问题。线程同步的目的在于确保多个线程能够有序地访问共享资源,避免...

    07Java 多线程编程1

    Java的多线程编程是开发高并发应用的关键技术之一,主要涉及到线程的创建、运行、调度、同步以及生命周期管理。下面将详细讲解这些知识点。 1. **线程的创建**: Java提供了两种创建线程的方式: - **实现...

    java核心知识,集合,多线程

    在这篇文章中,我们将深入探讨Java的集合框架和多线程这两个关键主题。 **Java集合框架** Java集合框架是Java SE API的一个重要组成部分,它提供了一种高效管理对象的方式。主要包含接口和类,如List、Set、Queue...

    01大数据面试复习----Java基础---集合类、多线程、JVM.zip

    在准备大数据面试的过程中,Java基础是必不可少的一部分,尤其聚焦于集合类、多线程和JVM这三大核心领域。下面将分别对这三个方面进行深入探讨。 **一、Java集合类** Java集合框架是处理对象组的重要工具,它包括...

    Java多线程与线程安全实践-基于Http协议的断点续传

    在单核CPU系统中,多线程是通过时间片轮转的方式让多个线程共享一个CPU核心,从而达到同时执行的效果。在多核CPU系统中,每个核心可以独立执行线程,进一步提高系统的并发能力。Java提供了一套完整的多线程模型,...

    作业6-线程同步实验-哲学家就餐问题.zip

    在这个“作业6-线程同步实验-哲学家就餐问题”的项目中,我们主要探讨的是多线程编程中的一个经典问题——哲学家就餐问题。这个问题由计算机科学家Edsger Dijkstra提出,旨在模拟五个哲学家在共享资源(筷子)时如何...

Global site tag (gtag.js) - Google Analytics