2010-10-28 8 views
114

Jak ustawić timer, powiedzmy na 2 minuty, aby spróbować połączyć się z bazą danych, a następnie wyrzucić wyjątek, jeśli wystąpi jakiś problem z połączeniem?Jak ustawić timer w Javie?

+1

Coul the OP wyjaśnić, czy chcą spróbować akcji przez co najmniej 2 minuty, czy też wyjątek musi być wyrzucony teraz później dwie minuty, nawet jeśli próba połączenia jest obecnie w toku – thecoshman

Odpowiedz

224

Pierwsza część odpowiedzi brzmi: jak zrobić to, o co pyta badana osoba, ponieważ tak ją początkowo zinterpretowałem i kilka osób uznało ją za pomocną. Od tego czasu pytanie zostało wyjaśnione i przedłużyłem odpowiedź, aby odpowiedzieć na to pytanie.

Ustawianie czasomierza

najpierw trzeba stworzyć timera (używam wersji java.util tutaj):

import java.util.Timer; 

..

Timer timer = new Timer(); 

Aby uruchomić Zadanie po zrobieniu:

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

Aby mieć powtórki zadanie po upływie okresu byłoby zrobić:

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

Making limit czasu zadania

konkretnie zrobić, co wyjaśnione pytanie dotyczy kwestii, które stara się wykonać zadanie dla w danym okresie czasu można wykonać następujące czynności:

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

Wykonanie zostanie wykonane normalnie z wyjątkami, jeśli zadanie zakończy się w ciągu 2 minut . Jeśli działa dłużej, wyjątek TimeoutException zostanie rzucony.

Jedną z kwestii jest to, że chociaż dostaniesz wyjątek TimeoutException po dwóch minutach, , zadanie będzie w dalszym ciągu działać, chociaż prawdopodobnie połączenie z bazą danych lub połączenie sieciowe ostatecznie przestanie działać i wygeneruje wyjątek w wątku. Ale pamiętaj, że może on zużywać zasoby do tego czasu.

+0

Oh, chyba masz mój problem źle, muszę wielokrotnie próbować łączyć się z bazą danych do 2 minut za każdym razem – Ankita

+1

Zaktualizowałem moją odpowiedź na pokrycie powtarzając co 2 minuty – andrewmu

+0

Przykro mi, ale moim wymaganiem jest to, że chcę dać 2 minuty na połączenie z bazą danych, a następnie po prostu wyśle ​​komunikat o błędzie. To tak, jakbym chciał ustawić limit czasu, aby spróbować połączyć się z bazą danych. – Ankita

9

Ok, myślę, że rozumiem teraz twój problem. Możesz użyć Przyszłości, aby spróbować coś zrobić, a potem trochę czasu, jeśli nic się nie wydarzy.

Np .:

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 
} 
+0

Wyjątek jest zgłaszany, ale program się nie kończy. Pomóż mi przez to: – Ankita

+2

Zamiast tego możesz użyć klasy ExecutorService Wykonawca ma metodę shutdown() do zatrzymania executora – Rites

+1

Executory połkną wyrzucone wyjątki, których nie obsługujesz w poleceniu Callable/Runnable, jeśli twój Runnable/Callable nie przechwytuje i nie obsługuje samego wyjątku i jest pod warunkiem, że jesteś przeciwny do niego, to musisz podklasować ScheduledExecutorService i przesłonić poExecute (pamiętaj, aby wywołać super.afterExecute()). Drugim argumentem afterExecute będzie tryb z Runnable/Callable – adam

6

Jak zatrzymać stoper?Zatrzymaj się i zagrać jeszcze raz, gdy coś zrobić w tym kodzie

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

Gdy używam timer.cancel();

będzie zatrzymać, ale jeśli zamknąć formularz i otworzyć go ponownie jest wyjątek

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Timer already cancelled. 
    at java.util.Timer.sched(Timer.java:354) 
    at java.util.Timer.scheduleAtFixedRate(Timer.java:296) 
    at View.Electronic_Meeting.this_componentShown(Electronic_Meeting.java:295) 
    at View.Electronic_Meeting.access$000(Electronic_Meeting.java:36) 
    at View.Electronic_Meeting$1.componentShown(Electronic_Meeting.java:85) 
    at java.awt.AWTEventMulticaster.componentShown(AWTEventMulticaster.java:162) 
    at java.awt.Component.processComponentEvent(Component.java:6095) 
    at java.awt.Component.processEvent(Component.java:6043) 
    at java.awt.Container.processEvent(Container.java:2041) 
    at java.awt.Component.dispatchEventImpl(Component.java:4630) 
    at java.awt.Container.dispatchEventImpl(Container.java:2099) 
    at java.awt.Component.dispatchEvent(Component.java:4460) 
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) 
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 
17

Wykorzystanie to

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

hmm ... this technicznie zadziałałby, z wyjątkiem tego, że nie obejmuje przypadków skrajnych, w których czas się kończy, W związku z przeprowadzaniem ankiety DB, w Które mogą być wymagane przez OP – thecoshman

+0

To jest jedyna poprawna odpowiedź. Będzie działał na jednym wątku i obliczy czas zakończenia bez dryfowania. Używanie TimerTask jest właśnie niewłaściwą rzeczą w tym przypadku. Byłem zaskoczony, jak wiele przykładów na StackOverflow sugeruje ten sam rodzaj źle kierowanej rzeczy. – AgilePro

+1

@thecoshman - implementacje timera NIE przerywają operacji DB, gdy jest ona w toku, ani tego nie robi. W każdym razie możesz kontrolować tylko czas uruchomienia operacji DB. Istnieje powszechne nieporozumienie, że potrzebny jest "zegar", aby czas rzeczy, ale nie. Musisz tylko ZROBIĆ coś, a używając aktualnego czasu, nie rób tego zbyt długo. – AgilePro

1
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); 
+0

wystarczy skopiować szkodnik powyżej kodu, będzie działał dobrze. Dałem dwa razy "czas" pierwszy jest po raz pierwszy, aby wykonać ten kod, a drugi jest dla przedziału czasowego. –