2012-04-03 4 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; 
    } 
} 

Я пытался сохранить все объекты JMS из класса Message за полученный в одну минуту на карте дерева против его точного времени как key.After завершение одной минуты, я хочу сериализовать карту и вернуть байт [] в другой класс. Тем временем я создаю новую карту деревьев для хранения следующего набора сообщений JMS в течение минуты. Этот код является некоторым, как не работает. Это дает мне ошибку java.lang.OutOfMemoryError: Java heap space. Также я заметил, что он продолжает писать только одно сообщение на карту, то есть, если сообщения были «привет», «хороший день для вас» - это два сообщения jms; класс StoreMessage получает одно сообщение за раз. Сначала он получит «привет», и как только это сообщение будет обработано, оно будет получать следующее сообщение. Но я заметил, что в течение одной минуты, когда поток не прерывается, он записывает только первое сообщение на карту и дает ошибку. Как это исправить?

+0

Что вы написали до сих пор? – doNotCheckMyBlog

+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) сначала? –

+0

Одна минута 60 секунд. Таким образом, хотя разность времени ниже 60 секунд. сделать некоторые операции. –

ответ

0

Так что я не совсем уверен, что вы пытаетесь выполнить в своем коде, но я думал, что по крайней мере дам отзывы.

Во-первых, вы работаете из памяти, потому что вы в призвании спина петли:

map1.put(precise_time, message); 

Это заполнит память очень быстро. Современные компьютеры достаточно быстры, чтобы создать не менее миллиона элементов дерева в секунду. Вам нужно как-то ограничить количество сделанных вами звонков put.

Далее, это очень странно, чтобы разветвить нить, чтобы вы могли interrupt() родительский поток в более позднее время. Вместо этого я бы сделал что-то вроде следующего, которое устанавливает значение stop-at-time-millis, а затем запускается до тех пор, пока не будет достигнуто время. Это полностью избавляет от 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 расчет неверен. Вы не можете взять число миллисекунд с эпохи и добавить их в nano-second значение System. Вероятно, вы переполнили long, если я не ошибаюсь. Фактически, расчет наносекунды был бы отрицательным значением, поэтому я не уверен, что вы пытались сделать там. Я бы просто использовал start_nanotime - System.nanoTime().
  • Вы не можете сделать b = serializer.serialize(map1); во внутреннем Thread. Это даже не компилируется, так как b должен был быть определен внутри потока или быть final.
  • Я не совсем понял new TreeMap<Long,Message>(); во внутреннем Thread, который просто создал бы TreeMap, который был бы немедленно помечен как мусор, так как вы его не назначили кому-либо. Может быть, вы хотели использовать map1.clear()?
  • Вы помещаете то же значение message в каждый элемент в TreeMap. Не уверен, что это то, что вы намеревались.
+0

Привет, Серый! Спасибо за ваш ответ. Этот код не дает мне никакой ошибки, но он не дает мне никаких результатов. Пожалуйста, помогите мне! – kuks

+0

Извините @kuks. Какой код? Мой код? Что вы ожидаете от вывода? – Gray

+0

Привет, Серый! Ну, если бы этот код работал правильно, ожидалось, что он вернет байт [] в другой класс, который его вызывает. Этот класс должен записать этот байт [] в непрозрачный набор данных базы данных HDF5 и создать файл с расширением h5. Я точно знаю, что в вызывающем классе нет ошибки, поскольку я выполнил ее довольно много раз раньше. Этот код класса в основном должен подключать мою структуру JMS и базу данных HDF5. Пожалуйста, Серый ... помоги мне ... Мне это нужно плохо! – kuks

0

Чтобы решить эту проблему, вам нужно будет работать с типом даты.

Для улучшения типа даты вы можете использовать joda-time или простую арифметику.

new 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 секунд.

Смежные вопросы