我的要求如下
loop(N times)
{
for(1 minute)
{
write certain values to a tree map
}
for(exactly after that above 1 min task)
{
serialize the tree map
return the tree map
create a new tree map
}
}
我如何达到这个目标?
这就是我到目前为止所做的......
public class StoreMessage {
private static long start_nanotime=System.nanoTime();
private static Thread thisThread = Thread.currentThread();
private static int timeToRun = 60000; // 1 minute
private static byte[] b=null;
public static Map <Long,Message> map1=new TreeMap<Long,Message>();
public static byte[] store(Message message){
new Thread(new Runnable(){
public void run(){
try{
sleep(timeToRun);
thisThread.interrupt();
b=serializer.serialize(map1);
new TreeMap<Long,Message>();
} catch(Exception e){
e.printStackTrace();
}
}
}).start();
while (!Thread.interrupted()) {
long precise_time=TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis())+(System.nanoTime()-start_nanotime);
map1.put(precise_time, message);
}
return b;
}
}
我试图在一分钟内将收到的消息类的所有JMS对象存储到树映射中,而不是作为键的精确时间。完成一分钟后,我希望序列化映射并将byte []返回给另一堂课。同时我创建了一个新的树映射来存储下一组JMS消息一分钟 这段代码是如何不工作的。它给了我 java.lang.OutOfMemoryError:Java堆空间的错误。另外我注意到它只向地图写了一条消息,即如果消息是“hi”,“祝你好日子” - 这些是两条消息; StoreMessage类一次收到一条消息..它首先收到“hi”,一旦处理完这条消息,它就会检索下一条消息。但我注意到,一分钟,当线程没有被中断时,它只将第一条消息写入地图并给出错误。我该如何解决这些问题?
答案 0 :(得分:0)
要解决该问题,您需要使用日期类型。
要改进日期类型,您可以使用joda-time或简单算术。
new Date()
- 为当前时刻创建Date实例。
Date date1 = new Date();
Thread.sleep(4000); //Do nothing for 4 sec
Date date2 = new Date();
long timeDiffInMs = date2.getTime() - date1.getTime();
timeDiffInMs的值应该更少,代表4秒。
答案 1 :(得分:0)
所以我不确定你要在代码中完成什么,但我认为我至少会对它提供一些反馈。
首先,你正在耗尽内存,因为你正在调用旋转循环:
map1.put(precise_time, message);
这将很快填充内存非常。现代计算机的速度足以创建至少一百万个每秒的树元素。您将需要以某种方式限制您拨打的put
电话的数量。
接下来,分叉一个线程非常很奇怪,以便以后可以interrupt()
父线程。相反,我会做类似以下的事情,它设置一个停止时间毫秒值,然后运行直到达到时间。这完全摆脱了Thread
。
long runUntilMillis = System.currentTimeMillis() + timeToRunMillis;
while (true) {
long now = System.currentTimeMillis();
if (now >= runUntilMillis) {
break;
}
long precise_time = ...
map1.put(precise_time, message);
}
return serializer.serialize(map1);
其他一些想法:
precise_time
计算不正确。您不能采用自纪元以来的毫秒数并将其添加到System
纳秒值。如果我没有弄错的话,你可能会溢出long
。实际上,纳秒计算本来是一个负值,所以我不确定你在那里做什么。我只想使用start_nanotime - System.nanoTime()
。b = serializer.serialize(map1);
中执行Thread
。这甚至都不会编译,因为b
必须在线程内定义,或者是final
。new TreeMap<Long,Message>();
中的Thread
,它会创建一个TreeMap
,它会立即标记为垃圾,因为您没有将其分配给任何人。也许您打算使用map1.clear()
?message
值添加到TreeMap
中的每个元素中。不确定这是你的意图。