зацикливание в Java для определенной продолжительности и определенной задачи - PullRequest
0 голосов
/ 03 апреля 2012

У меня есть следующее требование

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

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

Ответы [ 2 ]

0 голосов
/ 03 апреля 2012

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

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

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

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

Чтобы улучшить тип даты, вы можете использовать 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 секунды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...