分布式id生成器,互联网

简单的分布式id生成器,10位时间戳(秒)+自增id+2位机器id,应该能满足一般的应用了;原创,转载请注明出处

/**
 * 
* @Title: DistributedIdGenerator.java 
* @Description: 分布式id生成器 (10位时间戳(秒)+自增id+2位机器id)集群中能保证唯一(必须配置serverNums机器数)
* @date 2016年8月10日 
* @version V1.0
 */
public class DistributedIdGenerator {
		
	static String SERVER_ID_PREFIX=getServerId();
	
	static final String EMPTY="";
	

	final Map<Integer,Integer> secondSequenceMap=new ConcurrentHashMap<Integer, Integer>();

	
	public DistributedIdGenerator(int serverNums){
		
	}
	
	public DistributedIdGenerator(){
		
	}
	
	
	public synchronized long generateId(){
		long time = System.currentTimeMillis();
		int second=(int) (time/1000L);
		int sequence=0;
		if(secondSequenceMap.containsKey(second)){
			 sequence=secondSequenceMap.get(second);
		}else{
			secondSequenceMap.clear();
		}
		sequence++;
		secondSequenceMap.put(second, sequence);
		return Long.valueOf(second+EMPTY+sequence+SERVER_ID_PREFIX);
	}
	
	/**
	 * 此处有待斟酌 pid还是有概率会重复的(尽管加上了随机数)
	 * @return
	 */
	private static String getServerId(){
		String name = ManagementFactory.getRuntimeMXBean().getName();  
		String pid = name.split("@")[0]; 
		int random=new Random().nextInt(10);
		if(pid.length()<=1){
			pid=pid+""+random;
		}
		if(pid.length()>2){
			pid=pid.substring(0, 2);
		}
		if(random==0){
			random=1;
		}
		return random+pid;
	}
	
	public static void main(String[] args) throws Exception {
		final Map<Long,Long> sets = new ConcurrentHashMap<Long,Long>();
		final AtomicInteger counts = new AtomicInteger(0);

		final DistributedIdGenerator idGen = new DistributedIdGenerator(1);

		List<Callable<Long>> partitions = new ArrayList<Callable<Long>>();

		for (int i = 0; i < 100; i++) {
			partitions.add(new Callable<Long>() {
			
				@Override
				public Long call() throws Exception {
					for(int j=0;j<10000;j++){
						long id = idGen.generateId();
						System.out.println(id);
						if (sets.containsKey(id) ){
							counts.incrementAndGet();
						}
						sets.put(id, id);
					}
					return 0l;
				}
				
			});
		}
		ExecutorService executorPool = Executors.newFixedThreadPool(Runtime
				.getRuntime().availableProcessors()*4);
		try {
			long s = System.currentTimeMillis();
			executorPool.invokeAll(partitions);
			long s_avg = System.currentTimeMillis() - s;
			System.out.println("完成时间需要: " + s_avg / 1.0e3 + "秒");
			executorPool.shutdown();
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println("重复数:"+counts.get());
		long time = System.currentTimeMillis();
		int second=(int) (time/1000L);
		System.out.println(second);
	}
	

}


猜你喜欢

转载自tangzhibin.iteye.com/blog/2329760