参考storm中的RotatingMap实现key超时处理
storm0.8.1以后的RotatingMap完全可以独立于storm用来实现hashmap的key超时删除,并调用回调函数
RotatingMap.java:
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry; /**
* Expires keys that have not been updated in the configured number of seconds.
* The algorithm used will take between expirationSecs and
* expirationSecs * (1 + 1 / (numBuckets-1)) to actually expire the message.
*
* get, put, remove, containsKey, and size take O(numBuckets) time to run.
*
* The advantage of this design is that the expiration thread only locks the object
* for O(1) time, meaning the object is essentially always available for gets/puts.
*/
public class RotatingMap<K, V> {
//this default ensures things expire at most 50% past the expiration time
private static final int DEFAULT_NUM_BUCKETS = 3; public static interface ExpiredCallback<K, V> {
public void expire(K key, V val);
} private LinkedList<HashMap<K, V>> _buckets; private ExpiredCallback _callback; public RotatingMap(int numBuckets, ExpiredCallback<K, V> callback) {
if(numBuckets<2) {
throw new IllegalArgumentException("numBuckets must be >= 2");
}
_buckets = new LinkedList<HashMap<K, V>>();
for(int i=0; i<numBuckets; i++) {
_buckets.add(new HashMap<K, V>());
} _callback = callback;
} public RotatingMap(ExpiredCallback<K, V> callback) {
this(DEFAULT_NUM_BUCKETS, callback);
} public RotatingMap(int numBuckets) {
this(numBuckets, null);
} public Map<K, V> rotate() {
Map<K, V> dead = _buckets.removeLast();
_buckets.addFirst(new HashMap<K, V>());
if(_callback!=null) {
for(Entry<K, V> entry: dead.entrySet()) {
_callback.expire(entry.getKey(), entry.getValue());
}
}
return dead;
} public boolean containsKey(K key) {
for(HashMap<K, V> bucket: _buckets) {
if(bucket.containsKey(key)) {
return true;
}
}
return false;
} public V get(K key) {
for(HashMap<K, V> bucket: _buckets) {
if(bucket.containsKey(key)) {
return bucket.get(key);
}
}
return null;
} public void put(K key, V value) {
Iterator<HashMap<K, V>> it = _buckets.iterator();
HashMap<K, V> bucket = it.next();
bucket.put(key, value);
while(it.hasNext()) {
bucket = it.next();
bucket.remove(key);
}
} public Object remove(K key) {
for(HashMap<K, V> bucket: _buckets) {
if(bucket.containsKey(key)) {
return bucket.remove(key);
}
}
return null;
} public int size() {
int size = 0;
for(HashMap<K, V> bucket: _buckets) {
size+=bucket.size();
}
return size;
}
}
EventHandler.java
public class EventHandler<k, v> implements RotatingMap.ExpiredCallback<k, v>
{ @Override
public void expire(Object key, Object val)
{
System.out.println("key=" + key + ",val=" + val);
} }
RotatingMapStarter.java:
import java.sql.Date;
import java.text.SimpleDateFormat; public class RotatingMapStarter
{
RotatingMap<String, String> m_rotatingMap = null;
RotatingMap.ExpiredCallback<String, String> m_eventHandler = null;
long m_lastRotate = System.currentTimeMillis();
long m_rotateTime; @SuppressWarnings(
{ "unchecked", "rawtypes" })
public RotatingMapStarter(int n, int rotateTime) // rotateTime :rotate for
// second
{
m_eventHandler = new EventHandler<String, String>();
m_rotatingMap = new RotatingMap<String, String>(4, m_eventHandler);
m_lastRotate = System.currentTimeMillis();
m_rotateTime = 1000L * rotateTime; // millisecond
} public RotatingMap<String, String> getM_rotatingMap()
{
return m_rotatingMap;
} public void setM_rotatingMap(RotatingMap<String, String> m_rotatingMap)
{
this.m_rotatingMap = m_rotatingMap;
} public void StartConnMonitor()
{
Thread thread = new Thread("Server Monitor")
{
@SuppressWarnings("static-access")
public void run()
{
while (true)
{
try
{
Thread.currentThread().sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
} long now = System.currentTimeMillis();
if (now - m_lastRotate > m_rotateTime)
{
m_rotatingMap.rotate();
m_lastRotate = now; }
else
{
//System.out.println(now - m_lastRotate);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
System.out.println(df.format(new Date(now)));// new Date()为获取当前系统时间
}
}
}
}; thread.start();
} /**
* @param args
*/
public static void main(String[] args)
{
RotatingMapStarter rotatingMapStarter = new RotatingMapStarter(4, 10);
String value = "001";
String key = "value";
rotatingMapStarter.getM_rotatingMap().put(key, value);
rotatingMapStarter.StartConnMonitor();
} }
参考storm中的RotatingMap实现key超时处理的更多相关文章
- 关于MapReduce中自定义带比较key类、比较器类(二)——初学者从源码查看其原理
Job类 /** * Define the comparator that controls * how the keys are sorted before they * are pa ...
- storm源码之理解Storm中Worker、Executor、Task关系 + 并发度详解
本文导读: 1 Worker.Executor.task详解 2 配置拓扑的并发度 3 拓扑示例 4 动态配置拓扑并发度 Worker.Executor.Task详解: Storm在集群上运行一个To ...
- C++ STL中Map的按Key排序和按Value排序
map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区 分),我们用map来进 ...
- Storm中并发程度的理解
Storm中涉及到了很多组件,例如nimbus,supervisor等等,在参考了这两篇文章之后,对这个有了更好的理解. Understanding the parallelism of a Stor ...
- redis 在 php 中的应用(key篇)
本文为我阅读了 redis参考手册 之后结合 博友的博客 编写,注意 php_redis 和 redis-cli 的区别(主要是返回值类型和参数用法) 目录: KEY(键) DEL ...
- storm中的一些概念
1.topology 一个topolgy是spouts和bolts组成的图,通过stream groupings将图中的spout和bolts连接起来:如图所示: 一个topology会一直运行知道你 ...
- Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践
转: Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践 阿里加多 0.1 2018.03.23 17:19* 字数 492 阅读 2613评论 2喜欢 1 一.前 ...
- storm中worker、executor、task之间的关系
这里做一些补充: worker是一个进程,由supervisor启动,并只负责处理一个topology,所以不会同时处理多个topology. executor是一个线程,由worker启动,是运行t ...
- C++ STL中Map的按Key排序跟按Value排序
C++ STL中Map的按Key排序和按Value排序 map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定 ...
随机推荐
- 部署一个class文件
只发布一个class文件找到项目工作空间/target/class..根据项目结构找到修改的java文件编译的class文件比如RegexUtils.class使用SecureFXPortable将文 ...
- 关于String和StringBuffer的理解问题:指针、变量的声明、变量的值的变化
问题描述: 首先,看一个小的测试程序: public static void main(String[] args) { testStringBuffer test = new testStringB ...
- fedora 设置命令别名
用命令 alias 举例: alias ggw="g++ -g -Wall" ggw 是自定义的别名,可根据需要进行修改设置,等于后面的则是别名的具体含义,在终端输入ggw就像当于 ...
- ImageMagick 拼图及切图方法
ImageMagick 拼图方法1. 拼图montage *.jpg -tile 22x2 -geometry 64x256+0+0 10-.jpg将目录里的jpg文件按顺序拼成x轴22块,y轴2 ...
- iOS/Xcode异常:reason = “The model used to open the store is incompatible with the one used to create the store”
reason=The model used to open the store is incompatible with the one used to create the store 出现上述异常 ...
- leetcode先刷_Search in Rotated Sorted Array II
上一页下一页,找到相同的旋转阵列的问题.假设数组元素一再怎么办呢?会发生什么? 我给大家举一个极端的例子.如果是这样的阵列中的元件.1,1,2,1,1,1,1,我们想看看这个数组2,刚开始A[midd ...
- postgres-xc手册生成方法
步骤 检测编译环境 安装编译工具 编译 以上只在linux环境当中进行,本人所用系统ubuntu15.04 检测编译环境 在posgtgresql目录下运行./configure,并安装需要安 ...
- [转][Swust OJ 24]--Max Area(画图分析)
转载自:http://www.cnblogs.com/hate13/p/4160751.html Max Area 题目描述:(链接:http://acm.swust.edu.cn/problem/2 ...
- Android:Service的注意点以及一些知识点
1.自己练习service的start()方法开启一个service服务的时候,不管怎么开启按钮,就是开启不了service服务,控制台也没有报错信息, app不闪退,代码就那么几行.找了好久找不出来 ...
- No persister for 编译器每行执行两次的解决方法
是前台的 js 的 datagrid 部件加了 oncheck 事件引起