Wstrzymanie programu

0

Jak można zrobić np jakąś pętlę krążącą wokół przez 4s by wstrzymać program? Chcę po prostu opóźnić program np na 3 czy 4s inaczej niż przez sleep.

1

czemu inaczej niż przez sleep?

0

Użyj wątków.

0

Bo przez sleep coś mi nie wychodzi mam program działający przez sieć. W jednym wątku jest obsługa serwera(czy klienta w zależności od tego w jakim trybie działa) a w drugim obsługa gui (tak to sobie ułożyłem robię takie coś pierwszy raz nie wiem czy dobrze ale działa). Może to akurat nie jest tak istotne bo zatrzymanie potrzebne mi jest akurat w trybie pracy z komputerem a nie sieciowej więc tak naprawdę na tę chwile działa jakby tylko ten wątek z gui. To wstrzymanie ma symulować człowieka tzn ja jako użytkownik coś kliknę następuje odczekanie(jakby człowiek myślał) i robi coś komputer. Niestety gdy używam sleep robię to w ten sposób:
obsługa tego co robi użytkownik
Thread.sleep(3000);
obsługa tego co robi komputer
Działając w ten sposób wychodzi mi coś takiego:
Użytkownik coś klika i zamiast nastąpić od razu zmiana w gui program usypia a po 3s następuje od razu reakcja na to co klikną użytkownik oraz to co robi komputer. Zatrzymanie więc nie mam pojęcia czemu następuje szybciej przed reakcją w gui na to co robi człowiek.
Dlatego chcę spróbować inaczej.

No właśnie i okienko się blokuje to druga sprawa...

0

a nie ma w javie czegoś takiego jak timer?
wydaje się idealnym i prostym rozwiązaniem do tego co chcesz zrobić

0

Zajrzyj tutaj Time Line Events

Na drugiej podaj stronie poruszamy kwestię Timerów :)

Myślę, że w Twoim przypadku to by się nadało:

Timer timer = new Timer();
timer.schedulue(TimerTask, delay time, period time);

Tu masz jeszcze link do prostego budowania TimerTask
http://javaprogramming.awardspace.com/index.php?pokaz=_kurs&id=9

A tu dokumentacja klasy:
http://docs.oracle.com/javase/7/docs/api/java/util/Timer.html

0

Zapamiętaj sobie i powtarzaj jak mantrę do poduszki, że "Wątek GUI służy tylko do obsługi GUI".

  1. Nie wolno w nim odpalać sleep bo inaczej dojdzie do zatrzymania obsługi grafiki (nic nie będzie się rysować, ani odświeżać przez czas zatrzymania).
  2. Nie należy w nim również odpalać żadnych czasochłonnych obliczeń, ani rozbudowanych pętli (czyli krótko mówiąc obrabiać danych) bo spowolni się reakcje na mysz i klawiaturę (w tym ekrany dotykowe).
  3. Nie należy w nim sięgać do danych, które są synchronizowane ponieważ aktywna blokada dostępu zatrzyma go na jakiś moment. Objawami są lagi.
  4. Nie należy w nim otwierać żadnych plików, ani przeprowadzać żadnych operacji sieciowych ponieważ błędy operacji wejścia/wyjścia zatrzymają wątek, a problemy z odczytem/zapisem też spowodują lagi (te nieudane są powtarzane na niższych warstwach softu/hardware'u).
    Dwa ostatnie przypadki mogą doprowadzić do zakleszczenia, co nieodwołalnie załamie program, a użytkownika skłoni do jego skillowania (i zapewne odinstalowania zaraz potem).

Wywołuje się z niego tylko metody klas Swing takich jak np. JLabel.setText() czy JTable.setValueAt() z już przygotowanymi wcześniej (w innych wątkach) danymi. Dzięki temu gui aplikacji czy apleta będzie zawsze sprawnie działać nawet jeżeli obliczanie danych będzie długo trwać lub ktoś odpali taki program na czymkolwiek co jest po prostu wolne (a obsłuży Javę SE).

Dla początkujących problemem jest rozpoznanie co jest poruszane z wątku GUI (np. Swinga), czyli Evend Dispatch Thread, czyli EDT.
Krótka rozpiska:

  1. Każda zarejestrowana metoda obsługi listenera (jeżeli nie została wywołana jawnie przez Twoje metody z innych wątków).
  2. Każda metoda run anonimowego obiektu implementującego interfejs Runnable, która stała się argumentem metody SwingUtilities.invokeLater() lub invokeAndWait().
  3. Metoda actionPerformed() obiektu javax.swing.Timer
  4. Metody process() oraz done() obiektów dziedziczących po klasie SwingWorker.

Jeżeli jakaś metoda może być czasem wywołana przez Swinga, a czasem przez Twój kod, wtedy potrzebne jest Ci sprawdzenie czy jesteś w wątku EDT. Robi się to za pomocą wywołania funkcji metody EventQueue.isDispatchThread (lub SwingUtilities.isEventDispatchThread). Jej wywołanie nie ma sensu w obiektach klas anonimowych tworzonych na miejscu w przypadku (pkt.2):

SwingUtilities.invokeLater(new Runnable()
{
	@Override public void run()
	{
		//... Twój kod gui
	}
}

ponieważ nic innego takiego kodu nie wywoła (bez hakowania).
Chociaż jeżeli użyjesz czegoś takiego:

Runnable kombinuję;
SwingUtilities.invokeLater(kombinuję = new Runnable()
{
	@Override public void run()
	{
		//... wszystko inne
		if(SwingUtilities.isEventDispatchThread())
		{
			//... obsługa GUI
		}
		//... wszystko inne
	}
}
//...
kombinuję.run()

to sprawdzenie w kodzie czy jest w wątku EDT (tutaj po if) będzie jak najbardziej niezbędne.

Timer javax.swing.Timer, jest specjalnie przystosowany do używania przez aplikacje GUI, ponieważ zadanie odpalane w wywoływanej przez niego metodzie actionPerformed (->javadoc) jest uruchamiane zawsze w wątku EDT. Dzięki temu pozwala to uruchamiać wszystkie metody Swinga bez dodatkowego kombinowania z metodami invokeLater czy invokeAndWait.

Co do używania klasy java.util.Timer, to jest to stara klasa tworząca zawsze (niezbyt efektywnie) kolejny wątek, która w nowych implementacjach Javy (od 1.5) powinna być zastępowana przez egzekutora ScheduledThreadPoolExecutor. Można go dość łatwo skonfigurować do używania jednego wątku (->javadoc) i wtedy działa on identycznie jak ten Timer.

1 użytkowników online, w tym zalogowanych: 0, gości: 1