Zarządzanie czasem działania wątku

0

Mam problem z odpowiednim zarządzaniem czasem działania wątków. Chcę, żeby wykonywały się one przez określony przeze mnie czas i jeśli pewien warunek nie zostanie spełniony aby były zamykane. W przypadku gdyby warunek został spełniony chciałbym aby czas życia wątku leciał od nowa. Na razie mam coś takiego:

 public Klient(int id, long czas_zycia, Cukiernia cukiernia) {
		this.id = id;
		this.czas_zycia = czas_zycia;
		this.cukiernia = cukiernia;
		timer=new Timer();
		timer.schedule(new TimerTask() 
		{

			@Override
			public void run() {
				// TODO Auto-generated method stub
				czy_zyje=false;
				System.out.println("-------------Zmiana boolena---------------");
				
			}
			
		}, 1*1000);

	}

Powyżej w konstruktorze wątku tworzę sobie Timer, który po określonym czasie zmienia mi booleana w oparciu o który działa sam wątek:

@Override
	public void run() {
		
		long obecny_czas=System.currentTimeMillis();
		long koniec_zycia=czas_zycia+obecny_czas;
		//while(System.currentTimeMillis() < koniec_zycia) {
		while (czy_zyje) {
			try {
			long czas_spaceru=(long)(Math.random()*0.2*4000)+ System.currentTimeMillis();
			while(System.currentTimeMillis() < czas_spaceru) {
				System.out.println("Klient o nr: " + this.id + " spaceruje");
				try {
					Thread.sleep(500);
				} catch(Exception e) {
					
				}
			}
			
			if (czy_zyje==false) {
				break;
				
			}
			
			if ((!cukiernia.kolejka1.contains(this)) && (!cukiernia.kolejka2.contains(this))) {
				cukiernia.dodajKlientaDoKolejki(this);
			}
			if (czy_zyje==false) {
				break;
				
			}
			
		
			try {

				long time = (long) (Math.random() * 100);
				Thread.sleep(time*1000);
			} catch (Exception e) {

			}
			if (czy_zyje==false) {
				break;
				
			}
			
			
			try {
				if((cukiernia.kolejka1.contains(this)) || (cukiernia.kolejka2.contains(this))) {
					if ((cukiernia.kolejka1.element()==this) || (cukiernia.kolejka2.element()==this)) {
						zakupPaczka();
						cukiernia.usunKlientaZKolejki(this);
			}}
			} catch(Exception e) {
				System.out.println("aaaaaaaa");
			}
			
			if (czy_zyje==false) {
				break;
				
			}
		
			
			try {

				long time = (long) (Math.random() * 100);
				Thread.sleep(time*1000);
			} catch (Exception e) {

			}
			} finally {
				
				System.out.println("Klient nr: " + this.id + " umarl z braku paczkow");
			}
			
		}
		

	} 

Problem w tym, że ewentualna zmiana zostaje wychwycona dopiero po całym pierwszym przebiegu pętli. Nawalenie ifów i breaków połowicznie pomaga, ale zdaję sobie sprawę, że najprawdopodobniej jest to tragiczne rozwiązanie. Czy ktoś mógłby mi zaproponować ładniejsze i bardziej przejrzyste rozwiązanie?

Pozdrawiam

0

Co do tematu, to po pierwsze nie używaj System.currentTimeMillis() bo jest ona wrażliwa na przesunięcia zegara systemowego. Zamiast tego używa się System.nanoTime(). Używanie sleepów w pętli wątku, to bardzo słaby pomysł. Najczęściej nie ma żadnego sensu i często jest wynikiem złego podejścia do problemu.

Następne pytanie - po co chcesz zarządzać czasem działania wątków? Od jakiegoś już czasu wątek nie jest już podmiotem na którym należy się skupiać, lecz jest nim zadanie (Task, Runnable, Callable). W dzisiejszych czasach grzebanie w wątkach jest podobne do ręcznego sterowania pojedynczymi kołami w samochodzie. Napisz jaki problem potrzebujesz rozwiązać i z jakiego powodu przyszło Ci do głowy takie rozwiązanie, które chcesz zrealizować.

PS. Bardzo pobieżnie rzuciłem okiem na to spaghetti - formatuj kod czymkolwiek, byle było konsekwentnie i z usuwaniem zbędnych wierszy.
Przy takiej technice nie dowiesz się dlaczego dobry kod działa tak samo jak nie dowiesz się dlaczego zły nie działa. Kod ma być do czytania przez człowieka, a tylko przy okazji do łyknięcia przez kompilator. :)

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