参考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.假如存储学生和其成绩(假定 ...
随机推荐
- wiki oi 1044 拦截导弹
题目描述 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某 ...
- 笔试题&面试题:找出一个数组中第m小的值并输出
题目:找出一个数组中第m小的值并输出. 代码: #include <stdio.h> int findm_min(int a[], int n, int m) //n代表数组长度,m代表找 ...
- OpenStack导入镜像后Launch不起来的几个问题
Dashboard上显示state为error 没有其他报错 用nova list找到虚拟机的id 然后nova show,可以得到fault详细信息 也可以查看下面两个log /var/log/no ...
- ThinkPHP - 自动创建 + 自动验证 + 自动完成
自动创建:创建数据模型. $User->create(); 自动验证:验证提交的表单数据. protected $_validate = array( array('verify','requi ...
- C#构架之基础学习----动态添加窗体和 控件
仿照窗体应用程序编写: 任务一:生成一个Form类的窗体对象frm using System.Windows.Forms; //using指令使用Form对象创建所需的命名空间 //如 ...
- pkg_zhgl
CREATE OR REPLACE PACKAGE BODY PKG_ZHGL AS --账户管理包 code szn 20110829 --账户管理服务包 --定义本包中需要引用到的常量 --定义说 ...
- Python 迭代器、生成器、递归、正则表达式 (四)
一.迭代器&生成器 1.迭代器仅仅是一容器对象,它实现了迭代器协议.它有两个基本方法: 1)next 方法 返回容器的下一个元素 2)_iter_方法 返回迭代器自身.迭代器可以使用内建的it ...
- java-finalize
finalize()来自Object的protected 方法,同clone()需要用户具体实现.一.源码中的介绍1. Called by the garbage collector on an ...
- USACO Barn Repair 【贪心算法】
这到题目的题意不太好理解= = 看来还是英语太弱了 实际上题目给了你M, S, C 分别代表最多不超过M 块木板, S代表牛棚总数,C代表接下来有C个牛所在牛棚的标号 然后求的是如何安排方案,可以使得 ...
- 基于visual Studio2013解决C语言竞赛题之0516人来人往
题目