Java 同步和合并消息/数据流
它是关于非常常见的传感器数据处理问题 为了同步和合并来自不同来源的传感器数据,我想用Java实现它,而不需要太复杂的第三个libs或框架 比如说,我定义了一个对象(O),它由4个属性(A1,…A4)组成。这4个属性来自不同的数据通道,例如套接字通道 这4个属性通常以1.0~2.0 Hz的频率到达,并且它们的到达相互独立。 一旦有4个属性(A1,…A4)同时出现(在一个小时间窗口内,例如100ms),那么我将从这4个属性构造一个新对象(O) 下面是一个描述性的场景。 A1~A4的到达时间点标有* 对象O1~U3分别在t1、t2和t3的时间点上构造。 一些属性在t2和t3之间到达,但对于构建对象来说并不完整,因此它们 将被丢弃并忽略Java 同步和合并消息/数据流,java,concurrency,merge,messaging,sensors,Java,Concurrency,Merge,Messaging,Sensors,它是关于非常常见的传感器数据处理问题 为了同步和合并来自不同来源的传感器数据,我想用Java实现它,而不需要太复杂的第三个libs或框架 比如说,我定义了一个对象(O),它由4个属性(A1,…A4)组成。这4个属性来自不同的数据通道,例如套接字通道 这4个属性通常以1.0~2.0 Hz的频率到达,并且它们的到达相互独立。 一旦有4个属性(A1,…A4)同时出现(在一个小时间窗口内,例如100ms),那么我将从这4个属性构造一个新对象(O) 下面是一个描述性的场景。 A1~A4的到达时间点标有*
A1 * * * *
A2 * * * *
A3 * * *
A4 * * * *
--------|------------|-----------------|----------> time
t1 t2 t3
O1 O2 O3
一些要求:
- 将任何传入属性存储在时间离散存储桶的FIFO队列中(每个存储桶包含4个不同的属性)李>
- 同时运行一个无止境线程来检查FIFO队列(从队列的头部)是否有任何bucket已经被4个不同的属性填充。如果是,则构造一个对象并从队列中移除该bucket。如果铲斗未在特定时间窗口内完全装满,则会掉落
欢迎任何建议和更正 这不太可能解决您的问题,但它可能会为您指明正确的方向 我会第一次尝试使用谷歌番石榴:
ConcurrentMap<Key, Bucket> graphs = new MapMaker()
.expireAfterAccess(100, TimeUnit.MILLISECOND)
.makeComputingMap(new Function<Key, Bucket>() {
public Bucket apply(Key key) {
return new Bucket(key);
}
});
ConcurrentMap graphs=newmapmaker()
.expireAfterAccess(100,时间单位。毫秒)
.makeComputingMap(新函数(){
公共存储桶应用(密钥){
返回新铲斗(钥匙);
}
});
这将创建一个映射,其条目在100毫秒内未被访问时将消失,并在请求时创建一个新的bucket
我搞不清楚的是关键是什么:你真正想要的是队列形式的相同功能。这里有另一个疯狂的想法: 使用一个
LinkedBlockingQueue
将值写入所有传感器A1-A4
将此队列分配给AtomicReference
变量
创建计时器任务,该任务将以指定的间隔(100ms)将此队列切换为新队列
从旧队列中获取所有数据,并查看是否拥有所有数据A1-A4
如果是,则创建对象,否则删除所有内容这是另一种方法-不过这只是伪代码,您需要自己编写:)
类滑动窗口{
原子参考a1;
原子参考a2;
原子参考a3;
原子参考a4;
队列到达时间=新队列(4);
公共存储桶集合A1(对象数据){
a1.设置(数据);
现在=System.currentTimeInMillis()
long-OldEstarivalTime=arrivalTimes.pop();
到达时间。推(现在);
如果(现在-OldEstarivalTime<100){
返回buildBucket();
}
返回null;
}
公共存储桶集合A2(对象数据){。。。
...
私有Bucket buildBucket(){
铲斗b=新铲斗(a1、a2、a3、a4);
a1.清除();
a2.清除();
a3.清晰();
a4.清除();
返回b;
}
}
您可以这样做,get操作会一直阻塞直到数据到达,add操作不会阻塞。get操作可以稍微优化一下,以便将候选项保持在并行结构中,这样在过滤旧项时就不需要迭代所有候选项。但是,迭代4项应该快一点
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.LinkedBlockingQueue;
public class Filter<V> {
private static final long MAX_AGE_IN_MS = 100;
private final int numberOfSources;
private final LinkedBlockingQueue<Item> values = new LinkedBlockingQueue<Item>();
public Filter(int numberOfSources) {
this.numberOfSources = numberOfSources;
}
public void add(String source, V data) {
values.add(new Item(source, data));
}
public void get() throws InterruptedException {
HashMap<String, Item> result = new HashMap<String, Item>();
while (true) {
while (result.size() < numberOfSources) {
Item i = values.take();
result.put(i.source, i);
if (result.size() == numberOfSources) {
break;
}
}
//We got candidates from each source now, check if some are too old.
long now = System.currentTimeMillis();
Iterator<Item> it = result.values().iterator();
while (it.hasNext()) {
Item item = it.next();
if (now - item.creationTime > MAX_AGE_IN_MS) {
it.remove();
}
}
if (result.size() == numberOfSources) {
System.out.println("Got result, create a result object and return the items " + result.values());
break;
}
}
}
private class Item {
final String source;
final V value;
final long creationTime;
public Item(String source, V value) {
this.source = source;
this.value = value;
this.creationTime = System.currentTimeMillis();
}
public String toString() {
return String.valueOf(value);
}
}
public static void main(String[] args) throws Exception {
final Filter<String> filter = new Filter<String>(4);
new Thread(new Runnable() {
public void run() {
try {
filter.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
filter.add("a0", "va0.1");
filter.add("a0", "va0.2");
Thread.sleep(2000);
filter.add("a0", "va0.3");
Thread.sleep(100);
filter.add("a1", "va1.1");
filter.add("a2", "va2.1");
filter.add("a0", "va0.4");
Thread.sleep(100);
filter.add("a3", "va3.1");
Thread.sleep(10);
filter.add("a1", "va1.2");
filter.add("a2", "va2.2");
filter.add("a0", "va0.5");
}
}
import java.util.HashMap;
导入java.util.Iterator;
导入java.util.concurrent.LinkedBlockingQueue;
公共类过滤器{
私人静态最终长最大使用年限(单位:MS)=100;
私人最终信息来源;
私有最终LinkedBlockingQueue值=新LinkedBlockingQueue();
公共筛选器(int numberOfSources){
this.numberOfSources=numberOfSources;
}
公共void添加(字符串源,V数据){
添加(新项目(来源、数据));
}
public void get()抛出InterruptedException{
HashMap结果=新建HashMap();
while(true){
while(result.size()MAX_AGE_IN_MS){
it.remove();
}
}
if(result.size()==numberOfSources){
System.out.println(“获取结果,创建结果对象并返回项”+result.values());
打破
}
}
}
私人类项目{
最终字符串源;
最终V值;
最终创作时间长;
公众的
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.LinkedBlockingQueue;
public class Filter<V> {
private static final long MAX_AGE_IN_MS = 100;
private final int numberOfSources;
private final LinkedBlockingQueue<Item> values = new LinkedBlockingQueue<Item>();
public Filter(int numberOfSources) {
this.numberOfSources = numberOfSources;
}
public void add(String source, V data) {
values.add(new Item(source, data));
}
public void get() throws InterruptedException {
HashMap<String, Item> result = new HashMap<String, Item>();
while (true) {
while (result.size() < numberOfSources) {
Item i = values.take();
result.put(i.source, i);
if (result.size() == numberOfSources) {
break;
}
}
//We got candidates from each source now, check if some are too old.
long now = System.currentTimeMillis();
Iterator<Item> it = result.values().iterator();
while (it.hasNext()) {
Item item = it.next();
if (now - item.creationTime > MAX_AGE_IN_MS) {
it.remove();
}
}
if (result.size() == numberOfSources) {
System.out.println("Got result, create a result object and return the items " + result.values());
break;
}
}
}
private class Item {
final String source;
final V value;
final long creationTime;
public Item(String source, V value) {
this.source = source;
this.value = value;
this.creationTime = System.currentTimeMillis();
}
public String toString() {
return String.valueOf(value);
}
}
public static void main(String[] args) throws Exception {
final Filter<String> filter = new Filter<String>(4);
new Thread(new Runnable() {
public void run() {
try {
filter.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
filter.add("a0", "va0.1");
filter.add("a0", "va0.2");
Thread.sleep(2000);
filter.add("a0", "va0.3");
Thread.sleep(100);
filter.add("a1", "va1.1");
filter.add("a2", "va2.1");
filter.add("a0", "va0.4");
Thread.sleep(100);
filter.add("a3", "va3.1");
Thread.sleep(10);
filter.add("a1", "va1.2");
filter.add("a2", "va2.2");
filter.add("a0", "va0.5");
}
}