在java中循环一段时间和某个任务

时间:2012-04-03 10:01:53

标签: java loops

我的要求如下

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”,一旦处理完这条消息,它就会检索下一条消息。但我注意到,一分钟,当线程没有被中断时,它只将第一条消息写入地图并给出错误。我该如何解决这些问题?

2 个答案:

答案 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中的每个元素中。不确定这是你的意图。