Как выполнить цикл в течение определенного времени с помощью Java [duplicate]

Другим сценарием является то, что вы нанесли нулевой объект в тип значения . Например, код ниже:

object o = null;
DateTime d = (DateTime)o;

Он выкинет NullReferenceException в роли. В приведенном выше примере это кажется совершенно очевидным, но это может произойти в более «поздних связующих» сложных сценариях, где нулевой объект был возвращен из некоторого кода, которого вы не являетесь, и приведение, например, генерируется некоторой автоматической системой.

Одним из примеров этого является этот простой фрагмент привязки ASP.NET с элементом управления календарем:

" />

Здесь SelectedDate на самом деле является свойством - типа DateTime - типа Calendar Web Control, и привязка может отлично вернуть что-то null. Неявный генератор ASP.NET создаст кусок кода, который будет эквивалентен приведенному выше методу. И это поднимет NullReferenceException, что довольно сложно определить, потому что он лежит в сгенерированном ASP.NET коде, который компилирует отлично ...

23
задан Mat 6 October 2011 в 18:31
поделиться

12 ответов

Дизайн этого зависит от того, что вы хотите делать за 15 секунд. Два наиболее правдоподобных случая: «сделайте это каждый X за 15 секунд» или «дождитесь появления X или 15 секунд, что произойдет раньше», что приведет к очень разному коду.

Ожидание

Thread.sleep (15000)

Это не повторение, но если вы ничего не хотите делать за 15 секунд, это намного эффективнее (он тратит меньше процессор на то, чтобы ничего не делать) .

Повторите некоторый код для 15 секунд

Если вы действительно хотите зацикливаться на 15 секунд, тогда ваше решение будет прекрасным, если ваш код не займет слишком много времени. Что-то вроде:

long t= System.currentTimeMillis();
long end = t+15000;
while(System.currentTimeMillis() < end) {
  // do something
  // pause to avoid churning
  Thread.sleep( xxx );
}

Подождите 15 секунд или какое-либо другое условие

Если вы хотите, чтобы ваш код был прерван ровно 15 секунд, что бы он ни делал, вам понадобится многопоточный решение. Посмотрите на java.util.concurrent для множества полезных объектов. Большинство методов, которые блокируют (например, wait ()), имеют аргумент тайм-аута. Семафор может выполнять именно то, что вам нужно.

51
ответ дан Stephan 26 August 2018 в 20:24
поделиться

Никогда не проверяйте текущее время в плотной петле.

В противном случае кто-то с ноутбуком может получить, чтобы его / ее колпак загорелся перегретым процессором. Я слышал рассказы об этом на самом деле.

0
ответ дан Alexander Pogrebnyak 26 August 2018 в 20:24
поделиться

Как уже упоминалось в других плакатах, если вы хотите, чтобы поток некоторое время приостанавливался, используйте Thread.sleep().

Если вы хотите, чтобы нить что-то делал, но хотите остановить его после while, используйте что-то вроде:

class Foo implements Runnable {
    private volatile boolean killed = false;

    public void run() {
        while (!killed) {
            try { doOnce(); } catch (InterruptedException ex) { killed = true; }
        }
    }

    public void kill() { killed = true; }
    private void doOnce() throws InterruptedException { /* .. */ }
}

и из основного потока, do:

Foo foo = new Foo(); 
Thread thread = new Thread(foo);
thread.start();

/* when you want to stop it */
foo.kill();
thread.interrupt();
4
ответ дан Binil Thomas 26 August 2018 в 20:24
поделиться

Я предлагаю вам сделать это с помощью класса таймера, избегая Thread.sleep (xxx); метод.

, например:

import java.util.Timer;
import java.util.TimerTask;

public class TimerExample {
    private int globalTimer = 0;
    private int limitTimer = 15;

    public static void main(String[] args) {
        new TimerExample();
    }

    public TimerExample() {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                globalTimer++;
                // DO YOUR CODE HERE
                System.out.println("running");
                if (globalTimer == limitTimer) {
                    timer.cancel();
                }
            }
        }, 0, 1000);
    }
}
0
ответ дан Jason 26 August 2018 в 20:24
поделиться

попробуйте следующее:

public class SleepMessages {
    public static void main(String args[]) throws InterruptedException {
        String importantInfo[] = {
            "Mares eat oats",
            "Does eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };

        for (int i = 0; i < importantInfo.length; i++) {
            //Pause for 15 seconds
            Thread.sleep(15000);
            //Print a message
            System.out.println(importantInfo[i]);
        }
    }
}

подробнее: здесь

3
ответ дан Michel Gokan 26 August 2018 в 20:24
поделиться

Вот мое предложение, и оно работает хорошо для меня :)

StoppingTime = 15 ;
int loop = 1;
long StartTime = System.currentTimeMillis() / 1000 ;
for (int i=0; i<loop; ++i) {
    // your code here

    loop++;
    if (((System.currentTimeMillis()/1000) - StartTime) > StoppingTime)
        loop=0;
}
0
ответ дан nhahtdh 26 August 2018 в 20:24
поделиться

Решение, подобное @Tom Hawtin без размера сурового цикла.

final long end = System.nanoTime() + 15 * 1000 * 1000 * 1000L;
int loop = 1;
do {
    for (int i=0; i<loop; ++i) {
        ...
    }
    loop++;
} while (System.nanoTime() < end);

В этом случае размер внутренней петли начнет уменьшаться, но увеличится в размере, если цикл будет особенно быстрым. Если он достаточно медленный, он может выполнять только один раз.

0
ответ дан Peter Lawrey 26 August 2018 в 20:24
поделиться

Ваш общий подход кажется прекрасным, хотя вы можете посмотреть, больше ли текущее время, чем точка, которую вы хотите остановить, иначе вы могли бы работать в течение длительного времени.

Альтернативой является запустите таймер / поток, который устанавливает флаг через 15 секунд. Этот флаг должен быть отмечен как изменчивый, иначе ваш цикл может не увидеть изменения в значении.

Выбор, если вы заботитесь об эффективности, является более дорогостоящим, получая системное время один раз за цикл или доступ к изменчивой переменной? Я не знаю, какой из них более эффективен - вы можете сравнить его, если это действительно важно.

Для простого, поддерживаемого кода я бы выбрал подход проверки таймера:

long endTime = System.currentTimeMillis() + 15000
while (System.currentTimeMillis() < endTime) {
  //loop
} 
2
ответ дан Robert Christie 26 August 2018 в 20:24
поделиться

Для подхода java.util.concurrent см. главу 6 Java Concurrency in Practice (раздел 6.3.7. Установка временных ограничений для задач, стр. 131).

Пример кода: Получение рекламы с использованием бюджета времени.

0
ответ дан Steven G. Brown 26 August 2018 в 20:24
поделиться

Предполагая, что вы хотите, чтобы цикл делал что-то разумное, вы можете быстрее найти флажок волатильности. Еще один поток подождите 15 секунд (или используйте таймер), а затем установите его.

В качестве альтернативы, если вы знаете, сколько времени займет тело цикла, запустите его несколько сотен раз, скажем, и выполните

final long start = System.nanoTime();
do {
    for (int i=0; i<200, ++i) {
        ...
    }
} while (System.nanoTime()-start < 15L*1000L*1000L*1000L);

System.nanoTime должно не путаться изменениями системных часов. Важно использовать длинные литералы.

0
ответ дан Tom Hawtin - tackline 26 August 2018 в 20:24
поделиться

Вы можете использовать AOP и @Timeable аннотацию из jcabi-аспектов (я разработчик):

@Timeable(limit = 1, unit = TimeUnit.SECONDS)
String load(String resource) {
  // do this check regularly:
  if (Thread.currentThread.isInterrupted()) {
    throw new IllegalStateException("time out");
  }
  // execution as normal
}

Когда ограничение времени достигнет вашего потока, который установит флаг interrupted(), установленный на true, и ваше задание правильно справится с этой ситуацией и прекратит выполнение.

1
ответ дан yegor256 26 August 2018 в 20:24
поделиться

Возможно, вам будет интересно планировать TimerTask, который останавливает другой поток или изменяет состояние вашего цикла.

0
ответ дан YuppieNetworking 26 August 2018 в 20:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: