2012-04-03 35 views
-1

我有一個要求如下在java中循環一定時間和一定的任務

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; 
    } 
} 

我試圖將收到存儲在一分鐘到一棵樹地圖針對其精確的時間key.After類郵件的所有JMS對象完成一分鐘,我希望序列化該映射並將字節[]返回給另一個類。同時我創建一個新的樹形圖來存儲下一組JMS消息一分鐘 這段代碼有些不能工作。它給我錯誤java.lang.OutOfMemoryError:Java堆空間。另外我注意到它一直只寫一條消息給地圖,即如果消息是「嗨」,「對你很好的一天」 - 這是兩條jms消息; StoreMessage類一次接收一條消息......它會首先收到「hi」,一旦處理完這條消息,它就會檢索下一條消息。但是我注意到,整整一分鐘,當線程沒有中斷時,它只會將第一條消息寫入地圖並給出錯誤。我如何解決這些問題?

+0

你到目前爲止寫了些什麼? – doNotCheckMyBlog 2012-04-03 10:04:10

+1

通過閱讀[相應的Java教程](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html)[和Javadoc](http://docs.oracle.com/javase/6 /docs/api/java/lang/Object.html#wait%28long%29)先? – 2012-04-03 10:04:11

+0

一分鐘是60秒。所以雖然時差比60秒低。做一些操作。 – 2012-04-03 10:04:48

回答

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()
  • 你不能在內部Threadb = serializer.serialize(map1);。這將不會編譯,因爲b不得不在線程內定義或者是final
  • 我不明白像new TreeMap<Long,Message>();Thread這將只會創建一個TreeMap,因爲你沒有分配給任何人,它會立即被標記爲垃圾。也許你打算使用map1.clear()
  • 您正在將相同的message值放入TreeMap中的每個元素中。不確定那是你的意圖。
+0

Hi Gray!謝謝你的回覆..這段代碼不會給我任何錯誤,但它也不會給我任何輸出..請幫助我! – kuks 2012-04-04 14:09:17

+0

對不起@kuks。哪些代碼?我的代碼?你期望的輸出是什麼? – Gray 2012-04-04 14:13:06

+0

再次灰色!那麼,如果這段代碼能夠正常工作,那麼期望它將字節[]返回給正在調用它的另一個類。該類應該將此byte []寫入HDF5數據庫的不透明數據集,並創建一個帶有h5擴展名的文件。我確實知道調用類中沒有錯誤,因爲我已經執行了很多次這個類。這個類代碼基本上應該連接我的JMS結構和HDF5數據庫。請格雷......幫助我..我需要它! – kuks 2012-04-04 17:04:27

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秒。