Jak ustawić czasomierz, powiedzmy na 2 minuty, aby spróbować połączyć się z bazą danych, a następnie zgłosić wyjątek, jeśli jest jakiś problem w połączeniu?
Coul the OP wyjaśnij, czy chcą wykonać prostą czynność przez co najmniej 2 minuty, czy też wyjątek musi zostać wyrzucony teraz później po dwóch minutach, nawet jeśli próba połączenia jest obecnie w toku
thecoshman
Odpowiedzi:
280
Tak więc pierwsza część odpowiedzi dotyczy tego, jak zrobić to, o co prosi temat, ponieważ tak to początkowo zinterpretowałem i kilka osób wydawało się być pomocne. Pytanie zostało wyjaśnione i rozszerzyłem odpowiedź, aby je rozwiązać.
Ustawianie timera
Najpierw musisz utworzyć Timer (używam java.utilwersji tutaj):
import java.util.Timer;
..
Timer timer =newTimer();
Aby uruchomić zadanie po wykonaniu następujących czynności:
timer.schedule(newTimerTask(){@Overridepublicvoid run(){// Your database code here}},2*60*1000);// Since Java-8
timer.schedule(()->/* your database code here */,2*60*1000);
Aby zadanie było powtarzane po upływie czasu, który wykonasz:
timer.scheduleAtFixedRate(newTimerTask(){@Overridepublicvoid 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);
Wyznaczanie limitu czasu zadania
Aby konkretnie zrobić to, o co prosi wyjaśnione pytanie, czyli próbować wykonać zadanie przez określony czas, możesz wykonać następujące czynności:
ExecutorService service =Executors.newSingleThreadExecutor();try{Runnable r =newRunnable(){@Overridepublicvoid run(){// Database task}};Future<?> f = service.submit(r);
f.get(2,TimeUnit.MINUTES);// attempt the task for two minutes}catch(finalInterruptedException e){// The thread was interrupted during sleep, wait or join}catch(finalTimeoutException e){// Took too long!}catch(finalExecutionException e){// An exception from within the Runnable task}finally{
service.shutdown();}
Będzie to wykonywane normalnie z wyjątkami, jeśli zadanie zakończy się w ciągu 2 minut. Jeśli będzie działać dłużej, zostanie zgłoszony wyjątek TimeoutException.
Jednym z problemów jest to, że chociaż po dwóch minutach otrzymasz wyjątek TimeoutException, zadanie będzie nadal działać , chociaż prawdopodobnie połączenie z bazą danych lub siecią w końcu przekroczy limit czasu i zgłosi wyjątek w wątku. Ale pamiętaj, że zanim to się stanie, może zużywać zasoby.
Och, chyba źle zrozumiałeś mój problem, muszę wielokrotnie próbować połączyć się z bazą danych do 2 minut za każdym razem
Ankita
Przepraszam, ale moim wymaganiem jest to, że chcę dać 2 minuty na połączenie się z bazą danych, a potem po prostu wyskoczy jakiś komunikat o błędzie, tak jakbym chciał ustawić limit czasu na próbę połączenia się z bazą danych
Ankita
7
OSTRZEŻENIE CZYTELNIKÓW: Ta odpowiedź jest rażąco błędna. Ustawia czasomierz tak, aby czekał 2 minuty, a następnie uruchamia zapytanie DB po tym 2-minutowym opóźnieniu, a następnie uruchamia je ponownie i ponownie co 2 minuty. To, czego NIE robi, to natychmiastowe uruchomienie zapytania DB, a następnie niepowodzenie po 2 minutach, co moim zdaniem jest tym, o co pytano (jak wyjaśniono w komentarzu).
AgilePro,
2
@AgilePro To była prawda. Nie odpowiedziałem na pytanie, tak jak zostało ostatecznie określone, a teraz zaktualizowałem je, aby rozwiązać ten problem.
long startTime =System.currentTimeMillis();long elapsedTime =0L.while(elapsedTime <2*60*1000){//perform db poll/check
elapsedTime =(newDate()).getTime()- startTime;}//Throw your exception
hmm ... to technicznie by zadziałało, z wyjątkiem tego, że nie obejmuje skrajnych przypadków, w których kończy się czas, gdy wykonujesz ankietę DB, co może być wymagane przez OP
thecoshman
1
To jedyna poprawna odpowiedź. Będzie działać na jednym wątku i obliczy czas zakończenia bez dryftu. Używanie TimerTask jest w tym przypadku dokładnie niewłaściwą rzeczą. Zaskoczyło mnie, jak wiele przykładów na StackOverflow sugeruje ten sam rodzaj złej głowy.
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 rozpoczęcia operacji DB. Istnieje powszechne błędne przekonanie, że do odmierzania czasu potrzebny jest „zegar”, ale tak się nie dzieje. Musisz tylko coś ZROBIĆ i korzystając z aktualnego czasu upewnij się, że NIE ROBISZ TEGO zbyt długo.
AgilePro,
powiedzmy, że musisz albo zwrócić połączenie, albo wyrzucić po DOKŁADNIE dwóch minutach, to nie zadziała. tak się stanie, jeśli PO dwóch minutach próby połączenia nadal nie możesz się połączyć. W sytuacji, gdy sprawdzenie połączenia trwa, powiedzmy, dwa tygodnie, zgłoszenie wyjątku zajmie tyle czasu.
thecoshman,
14
W rzeczywistości jest to bardzo zły styl kodowania, ponieważ pętla while stale działa i sprawdza, czy coś jest ... złe dla procesora i źle dla żywotności baterii.
Infinite
11
Ok, myślę, że teraz rozumiem twój problem. Możesz użyć Future, aby spróbować coś zrobić, a następnie po pewnym czasie wygasnąć, jeśli nic się nie wydarzyło.
Na przykład:
FutureTask<Void> task =newFutureTask<Void>(newCallable<Void>(){@OverridepublicVoid call()throwsException{// Do DB stuffreturnnull;}});Executor executor =Executors.newSingleThreadScheduledExecutor();
executor.execute(task);try{
task.get(5,TimeUnit.SECONDS);}catch(Exception ex){// Handle your exception}
Zgłoszono wyjątek, ale program nie zostaje zakończony. Proszę, pomóż mi w tym.
Ankita
2
Zamiast klasy Executor można użyć klasy ExecutorService. Posiada metodę shutdown () do zatrzymania executora.
Rites
1
Egzekutorzy będą połykać wyrzucane wyjątki, których specjalnie nie obsługujesz w swoim Wywołalnym / Wykonalnym. Jeśli Twój Runnable / Callable nie przechwytuje i nie obsługuje samego wyjątku, a jest on dostarczany do Ciebie, a nie do Ciebie, do którego jesteś właścicielem, musisz podklasować ScheduledExecutorService i przesłonić afterExecute (pamiętaj, aby wywołać super.afterExecute ()). Drugim argumentem do afterExecute będzie rzut z Runnable / Callable
adam
3
new java.util.Timer().schedule(newTimerTask(){@Overridepublicvoid run(){System.out.println("Executed...");//your code here //1000*5=5000 mlsec. i.e. 5 seconds. u can change accordngly }},1000*5,1000*5);
Odpowiedzi:
Tak więc pierwsza część odpowiedzi dotyczy tego, jak zrobić to, o co prosi temat, ponieważ tak to początkowo zinterpretowałem i kilka osób wydawało się być pomocne. Pytanie zostało wyjaśnione i rozszerzyłem odpowiedź, aby je rozwiązać.
Ustawianie timera
Najpierw musisz utworzyć Timer (używam
java.util
wersji tutaj):..
Aby uruchomić zadanie po wykonaniu następujących czynności:
Aby zadanie było powtarzane po upływie czasu, który wykonasz:
Wyznaczanie limitu czasu zadania
Aby konkretnie zrobić to, o co prosi wyjaśnione pytanie, czyli próbować wykonać zadanie przez określony czas, możesz wykonać następujące czynności:
Będzie to wykonywane normalnie z wyjątkami, jeśli zadanie zakończy się w ciągu 2 minut. Jeśli będzie działać dłużej, zostanie zgłoszony wyjątek TimeoutException.
Jednym z problemów jest to, że chociaż po dwóch minutach otrzymasz wyjątek TimeoutException, zadanie będzie nadal działać , chociaż prawdopodobnie połączenie z bazą danych lub siecią w końcu przekroczy limit czasu i zgłosi wyjątek w wątku. Ale pamiętaj, że zanim to się stanie, może zużywać zasoby.
źródło
Użyj tego
źródło
Ok, myślę, że teraz rozumiem twój problem. Możesz użyć Future, aby spróbować coś zrobić, a następnie po pewnym czasie wygasnąć, jeśli nic się nie wydarzyło.
Na przykład:
źródło
źródło
[Android], jeśli ktoś chce zaimplementować zegar na Androida za pomocą java .
źródło