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

自己做的 取sequence的 使用blockingqueue 和 ScheduledExecutorService例子

 
阅读更多
引用


在取 sequence的 dao里 用了一个 mock的 实现 ,然后 把queue的容量设置为3, 但是每次取可以取到4
这样第一次会把第4个元素 不放进去, 只放进去3个 ,




package com.ssc.dbcttool.seqgenerator;

import java.util.List;

public interface KeyDao {
	List<Long> getSequences(String seqName, Long capbility);
	
	
}


package com.ssc.dbcttool.seqgenerator;

import java.util.ArrayList;
import java.util.List;

public class MockKeyDao implements KeyDao{

	@Override
	public List<Long> getSequences(String seqName, Long capbility) {
		List<Long> longList = new ArrayList<Long>();
		longList.add(1000L);
		longList.add(1001L);
		longList.add(1010L);
		longList.add(1100L);
		
		return longList;
	}
	
	
	
}






package com.ssc.dbcttool.seqgenerator;

public class KeyGeneratorClient {
	
	public static void main(String[] args) {
		
		SeqGeneratorImpl gen = new SeqGeneratorImpl();
		gen.setGenerateKeysDao(new MockKeyDao());
		
		System.out.println("key = " + gen.getSeqKey("aaa"));
		System.out.println("key = " + gen.getSeqKey("aaa"));
		System.out.println("key = " + gen.getSeqKey("aaa"));
		System.out.println("key = " + gen.getSeqKey("aaa"));
		System.out.println("key = " + gen.getSeqKey("aaa"));
		System.out.println("key = " + gen.getSeqKey("aaa"));
		System.out.println("key = " + gen.getSeqKey("aaa"));
		System.out.println("key = " + gen.getSeqKey("aaa"));
		System.out.println("key = " + gen.getSeqKey("aaa"));
		
	}

}




package com.ssc.dbcttool.seqgenerator;

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

import com.statestr.gcth.core.concurrency.DefaultThreadFactory;

public class SeqGeneratorImpl {

	final int capacity = 3;

	ConcurrentMap<String, BlockingQueue<Long>> keyQueues = new ConcurrentHashMap<String, BlockingQueue<Long>>();

	ScheduledExecutorService scheduler;

	public SeqGeneratorImpl() {
		scheduler = new ScheduledThreadPoolExecutor(2, new DefaultThreadFactory().daemon().eh(
				new UncaughtExceptionHandler() {
					public void uncaughtException(Thread t, Throwable e) {
						System.out.println("Thread " + t.getName()
								+ " for Key Generator throw a UncaughtException.");
					}
				}));
	}
	
	public Long getSeqKey(String keyName) {
		Long key = null;
		BlockingQueue<Long> keyQueue =  keyQueues.get(keyName);

		if (keyQueue == null) {
			keyQueue = getQueue(keyName);
		}

		try {
			key = keyQueue.take();
		} catch (Exception e) {
			Thread.currentThread().interrupt();
			System.out.println("Failed to get sequence for unknown reason, the operation is interrupted.");
		}
		return key;
	}
	
	synchronized BlockingQueue<Long> getQueue(String keyName) {
		BlockingQueue<Long> keyQueue = keyQueues.get(keyName);
		if (keyQueue == null) {
			keyQueue = new LinkedBlockingQueue<Long>(capacity);
			keyQueues.putIfAbsent(keyName, keyQueue);
			triggerTheTask(keyName, keyQueue);
		}
		return keyQueue;
	}

	void triggerTheTask(String name, BlockingQueue<Long> keyQueue) {
		scheduler.scheduleWithFixedDelay(new FetchKeyTask(name, keyQueue), 0,
				3000, TimeUnit.MILLISECONDS);
	}

	protected class FetchKeyTask implements Runnable {

		private String keyName;
		private BlockingQueue<Long> keyQueue = null;

		public FetchKeyTask(BlockingQueue<Long> keyQueue) {
			this(null, keyQueue);
		}

		public FetchKeyTask(String keyName, BlockingQueue<Long> keyQueue) {
			this.keyName = keyName;
			this.keyQueue = keyQueue;
		}

		@Override
		public void run() {

			int remainingCapacity = keyQueue.remainingCapacity();
			if (capacity * (1 - 0.5) < remainingCapacity) {
				try {
					List<Long> keys = getKeys(keyName, remainingCapacity);
					for (Long key : keys) {
						keyQueue.put(key);
					}
				} catch (InterruptedException e) {
					Thread.currentThread().interrupt();
					System.out.println("key fetch task is interrupted.");
				} catch (Exception e) {
					System.out.println("key fetch task happens exception:");
				}
				System.out.println("retrieve keys from database, the keys' amount is "
						+ remainingCapacity);
			}
		}
	}
	
	protected List<Long> getKeys(String name, long capacity) {
		return generateKeysDao.getSequences(name, capacity);
	}
	
	protected KeyDao generateKeysDao;
	
	public void setGenerateKeysDao(KeyDao generateKeysDao) {
		this.generateKeysDao = generateKeysDao;
	}
	
}

分享到:
评论

相关推荐

    oracle 存储过程使用 sequence

    以下是一个简单的例子,展示了如何在存储过程中使用Sequence生成用户ID: ```plsql CREATE OR REPLACE PROCEDURE INSERT_USER ( p_username IN VARCHAR2, p_email IN VARCHAR2, p_user_id OUT NUMBER) AS BEGIN ...

    使用JDeveloper开发WEB应用时同时使用Oracle的sequence和trigger

    本篇将重点介绍如何在使用JDeveloper这款强大的集成开发环境(IDE)时,结合Oracle的sequence和trigger来实现高效的数据操作。 首先,让我们理解一下sequence和trigger的概念。在Oracle中,sequence是一种自动递增...

    Sequence to Sequence Learning with Neural Networksv论文

    《Sequence to Sequence Learning with Neural Networks》是一篇由Ilya Sutskever, Oriol Vinyals和Quoc V. Le共同撰写的论文,三位作者都来自Google公司。这篇论文在自然语言处理领域有着重要的影响,特别是在序列...

    sequence等同于序列号

    在这个例子中,`emp_sequence`是一个名为“emp”的表生成主键所使用的序列。每次调用`NEXTVAL`方法时,`sequence`值将递增1,并且从1开始计数。如果不设置最大值,则默认为无上限。此外,还可以选择是否让`sequence`...

    sequence-diagram.zip

    sequence-diagram-js是一个基于JavaScript的开源库,用于生成序列图,其特色在于支持自定义颜色,使得设计出的序列图更具个性化和可读性。本篇文章将深入探讨sequence-diagram-js的核心功能,依赖库,以及如何使用...

    Activiti 学习笔记七:连线(SequenceFlow)

    本篇学习笔记将深入探讨SequenceFlow的概念、作用以及如何在流程设计中使用。 一、SequenceFlow简介 SequenceFlow 是 Activiti 流程模型中的概念,它表示了流程实例从一个活动(Activity)到另一个活动的流转。每个...

    NumberSequence

    总之,了解并正确使用AX中的Number Sequence对于企业的数据管理和流程效率至关重要。它不仅简化了编号过程,还确保了数据的完整性和合规性。通过上述步骤,用户可以自定义并维护适合其业务需求的Number Sequence,...

    SequenceDiagram-3.0.5.zip

    在使用 SequenceDiagram-3.0.5 时,用户应当先了解序列图的基本概念和用法,然后根据需求选择合适的方式创建和编辑图。如果软件包含代码生成功能,要确保生成的代码符合项目的编码规范和设计模式。同时,定期检查...

    oracle中的sequence实现主键增长

    以下是对Sequence创建和使用的详细说明: 1. **创建Sequence**: 使用`CREATE SEQUENCE`语句创建Sequence,例如: ```sql CREATE SEQUENCE S_Depart_sqs INCREMENT BY 1 START WITH 1 NOMAXVALUE NOCYCLE ...

    Medoc sequence generator.zip三菱PLC编程案例源码资料编程控制器应用通讯通信例子程序实例

    Medoc sequence generator.zip三菱PLC编程案例源码资料编程控制器应用通讯通信例子程序实例Medoc sequence generator.zip三菱PLC编程案例源码资料编程控制器应用通讯通信例子程序实例Medoc sequence generator.zip...

    SequenceDiagram.zip

    **SequenceDiagram.zip** 文件包含的资源显然专注于在Windows .NET环境中使用序号图的实现。这个控件提供了一个动态的可视化平台,允许用户以UML标准的方式查看和理解对象间的交互。这种控件的亮点在于其**类似调试...

    Oracle sequence 重置(失效恢复)

    然后,我们使用一个PL/SQL块来遍历所有需要重置的Sequence,并根据表中的最大主键值来设置Sequence的起始值。 #### 1. 定义函数`func_getseq` ```sql CREATE OR REPLACE FUNCTION func_getseq (in_table VARCHAR2)...

    invalid multibyte character sequence 870告警1

    在计算机科学中, Multibyte Character Sequence 指的是使用多个字节来表示一个字符的编码方式。这种编码方式主要用于表示非ASCII字符,例如中文字符。在Unicode标准中,每个字符可以使用多个字节来表示,例如UTF-8...

    Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍

    一旦定义了 SEQUENCE,可以使用 CURRVAL 和 NEXTVAL 来获取当前值和下一个值。CURRVAL 返回当前 SEQUENCE 的值,NEXTVAL 增加 SEQUENCE 的值,然后返回增加后的值。 例如,使用 S_S_DEPART SEQUENCE.insert 一个新...

    Informatica中Sequence Generator的两个有用的选项

    在实际应用中,选择 Cycle 或 Reset 选项取决于具体的业务需求和系统限制。例如,如果系统需要序列号的唯一性非常高,可以选择 Reset 选项,而如果系统对序列号的唯一性没有特别限制,可以选择 Cycle 选项。...

    Sequence简单介绍.pdf

    可以通过`CREATE SEQUENCE`语句创建一个序列,并且能够通过`NEXTVAL`和`CURRVAL`来获取序列的下一个值以及当前值。 - **创建序列**: 使用`CREATE SEQUENCE`命令来定义序列。 ```sql CREATE SEQUENCE emp_sequence...

    oracle中sequence介绍及应用

    Sequence常用于为表中的某列自动生成唯一的主键值或者作为流水号使用。 #### 二、Sequence的创建与基本属性 ##### 创建Sequence的基本语法如下: ```sql CREATE SEQUENCE [start WITH n] -- 开始位置,默认递增...

    sequence-to-sequence learning

    机器学习之sequence to sequence learning。(Sequence Generation-----Hung-yi Lee 李宏毅.ppt)

Global site tag (gtag.js) - Google Analytics