Як встановити таймер на Java?


151

Як встановити Таймер, скажімо, на 2 хвилини, щоб спробувати підключитися до Бази даних, а потім викинути виключення, якщо є якась проблема в зв'язку?


1
Coul OP роз'яснить, чи хочуть вони просту спробувати дію принаймні на 2 хвилини, чи виняток потрібно кинути вже пізніше дві хвилини, навіть якщо зараз триває спроба підключення
thecoshman

Відповіді:


280

Отже, перша частина відповіді полягає в тому, як робити те, що запитує, тому що я спочатку інтерпретував це, і мало хто здався корисним. Питання було роз'яснено, і я відповів на це питання.

Встановлення таймера

Спочатку вам потрібно створити таймер (я java.utilтут використовую версію):

import java.util.Timer;

..

Timer timer = new Timer();

Щоб виконати завдання, як тільки ви зробите:

timer.schedule(new TimerTask() {
  @Override
  public void run() {
    // Your database code here
  }
}, 2*60*1000);
// Since Java-8
timer.schedule(() -> /* your database code here */, 2*60*1000);

Щоб завдання повторилося після тривалості, яку ви зробили б:

timer.scheduleAtFixedRate(new TimerTask() {
  @Override
  public void run() {
    // Your database code here
  }
}, 2*60*1000, 2*60*1000);

// Since Java-8
timer.scheduleAtFixedRate(() -> /* your database code here */, 2*60*1000, 2*60*1000);

Створення тайм-ауту завдання

Щоб конкретно виконати те, що задається уточненим запитанням, тобто спробою виконати завдання за певний проміжок часу, ви можете зробити наступне:

ExecutorService service = Executors.newSingleThreadExecutor();

try {
    Runnable r = new Runnable() {
        @Override
        public void run() {
            // Database task
        }
    };

    Future<?> f = service.submit(r);

    f.get(2, TimeUnit.MINUTES);     // attempt the task for two minutes
}
catch (final InterruptedException e) {
    // The thread was interrupted during sleep, wait or join
}
catch (final TimeoutException e) {
    // Took too long!
}
catch (final ExecutionException e) {
    // An exception from within the Runnable task
}
finally {
    service.shutdown();
}

Це буде виконуватись за винятком випадків, якщо завдання буде виконано протягом 2 хвилин. Якщо він працює довше, TimeoutException буде кинутим.

Одне питання полягає в тому, що, хоча ви отримаєте TimeoutException через дві хвилини, завдання фактично продовжуватиметься виконуватись , хоча, мабуть, база даних або мережеве з'єднання врешті-решт вичерпаються та викинуть виняток у потоці. Але пам’ятайте, що він може споживати ресурси, поки цього не станеться.


О, я думаю, ви помилилися з моєю проблемою, я мушу неодноразово намагатися підключитися до бази даних щоразу до 2 хвилин
Ankita

Мені шкода, але моя вимога полягає в тому, що я хочу дати 2 хвилини на підключення до бази даних, і тоді це просто кине якесь повідомлення про помилку. Це так, як я хочу встановити обмеження часу, щоб спробувати підключитися до бази даних
Ankita

7
ЧИТАТИ БЕЗПЕЧНО: Ця відповідь очевидно неправильна. Він встановлює таймер, щоб зачекати 2 хвилини, а потім запустити запит БД після цієї 2-хвилинної затримки, а потім він запускає його знову і знову кожні 2 хвилини. Що НЕ робиться - це запустити запит БД відразу, а потім вийти з ладу через 2 хвилини. Це, на мій погляд, запитання (як пояснено в коментарі).
AgilePro

2
@AgilePro Це було правдою. Я не відповів на питання, як це було врешті-решт заявлено, і зараз я його оновив для вирішення цього питання.
andrewmu

1
@ErnestasGruodis Основні API зазначають конструктор як загальнодоступний: docs.oracle.com/javase/7/docs/api/java/util/Timer.html#Timer () У вашому класі може бути інший клас Таймера - спробуйте java. util.Timer як клас.
andrewmu

25

Використовуй це

long startTime = System.currentTimeMillis();
long elapsedTime = 0L.

while (elapsedTime < 2*60*1000) {
    //perform db poll/check
    elapsedTime = (new Date()).getTime() - startTime;
}

//Throw your exception

1
хм ... це технічно спрацює, за винятком випадків, коли це не стосується крайових випадків, коли у вас закінчується час, коли ви виконуєте опитування БД, яке може знадобитися ОП
thecoshman

1
Це єдина правильна відповідь. Він буде працювати на одній нитці і обчислює час закінчення без дрейфу. Використання TimerTask - це неправильна справа в цьому випадку. Я здивований тим, скільки прикладів на StackOverflow підказують таку саму річ із неправильним головою.
AgilePro

1
@thecoshman - реалізація таймера НЕ перериває операцію БД після її запуску, а також цього не робить. У будь-якому випадку ви можете контролювати лише час запуску операції з БД. Існує поширена помилка, що вам потрібен "таймер" для того, щоб вчасно обробляти речі, але ви цього не робите. Вам потрібно лише щось зробити, і, використовуючи поточний час, переконайтеся, що ви НЕ робите це занадто довго.
AgilePro

скажімо, вам доведеться або повернути з'єднання, або кинути через РОЗБІРНО дві хвилини, це не вийде. це станеться, якщо ПІСЛЯ двох хвилин спроби підключитися, ви все ще не вдалося підключитися. У ситуації, коли перевірка підключення займає, наприклад, два тижні, для винятку буде потрібно багато часу.
thecoshman

14
Це насправді дуже поганий стиль кодування, оскільки цикл у той час як постійно працює і перевіряє наявність матеріалів ... поганий для процесора і поганий час роботи акумулятора.
Нескінченний

11

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

Наприклад:

FutureTask<Void> task = new FutureTask<Void>(new Callable<Void>() {
  @Override
  public Void call() throws Exception {
    // Do DB stuff
    return null;
  }
});

Executor executor = Executors.newSingleThreadScheduledExecutor();
executor.execute(task);

try {
  task.get(5, TimeUnit.SECONDS);
}
catch(Exception ex) {
  // Handle your exception
}

Виняток кидається, але програма не припиняється. Допоможіть мені про це.
Анкіта

2
Ви можете використовувати клас ExecutorService замість Executor. Він має метод shutdown () для зупинки виконавця.
Обряди

1
Виконавці проковтнуть викинуті винятки, з якими ви спеціально не обробляєтесь у програмі Callable / Runnable. Якщо ваш Runnable / Callable не вловлює і не обробляє виняток сам, і він надається вам проти того, яким ви володієте ним, вам потрібно підкласифікувати ScheduledExecutorService і замінити команду afterExecute (обов'язково зателефонуйте super.afterExecute ()). Другим аргументом для AfterExecute буде передача з Runnable / Callable
adam

3
    new java.util.Timer().schedule(new TimerTask(){
        @Override
        public void run() {
            System.out.println("Executed...");
           //your code here 
           //1000*5=5000 mlsec. i.e. 5 seconds. u can change accordngly 
        }
    },1000*5,1000*5); 

просто скопіюйте шкідника над кодом, він буде добре працювати. Я дав два рази "час", це перший раз для виконання цього коду, а другий - для інтервального часу.
Махадев Мане

Документація для Таймера рекомендує замість цього використовувати рамку Executor. docs.oracle.com/javase/10/docs/api/java/util/Timer.html
Каран Ханна

1

[Android], якщо хтось хоче реалізувати таймер на андроїд за допомогою Java .

для виконання операцій вам потрібно використовувати такий потік інтерфейсу користувача .

Timer timer = new Timer();
timer.schedule(new TimerTask() {
           @Override
            public void run() {
                ActivityName.this.runOnUiThread(new Runnable(){
                    @Override
                      public void run() {
                       // do something
                      }        
                });
            }
        }, 2000));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.