Kolejność wykonywania się wątków

0

Witam. Mam jeden problem. Googlowałem, szukałem tutaj i jakoś nie mogę znaleźć rozwiązania.

Mam trzy wątki: A, B, C. Chcę żeby wykonywały się one po kolei, jeden po drugim. Wiem, że łatwiej byłoby po prostu zrobić pętlę i w niej wykonywać to co chcę w kolejności, ale takie dostałem ćwiczenie.

class A implements Runnable {
	public void run() {
		while (true) { 
			// robię parę rzeczy
			// ...
			// przelaczam sie do watku B
		}
	}
}

class B implements Runnable {
	public void run() {
		while (true) { 
			// robię parę rzeczy
			// ...
			// przelaczam sie do watku C
		}
	}
}

class C implements Runnable {
	public void run() {
		while (true) { 
			// robię parę rzeczy
			// ...
			// przelaczam sie do watku A
		}
	}
}


public class Main {
	public static void main(String[] args) throws InterruptedException {
		ExecutorService exec = Executors.newCachedThreadPool();
		exec.execute(new A());
		exec.execute(new B());
		exec.execute(new C());
		exec.shutdown();
	}
}

Jak tego dokonać?

0

Tak jak to napisałeś, to odpalą się równolegle.
Musisz skorzystać z wait i notify oraz jakiegoś obiektu współdzielonego przez wszystkie 3 wątki kontrolującego, który ma się w danej chwili wykonywać.

Tu jest szkic rozwiązania (nie gotowe rozwiązanie, jeszcze trzeba ustawić we wszystkich commonThreadController i wystartować wątki):

class ThreadController {
  int currentThread = 1;
}

class MyThread1 extends Thread {
   
   ThreadController commonThreadController; 
   
   public void run() {
     synchronized(commonThreadController) {
        while (commonThreadController.currentThread != 1)
           commonThreadController.wait();
        //..... zrob cos  

        commonThreadController.currentThread++;
        commonThreadController.notify();
     }     
   }
}

class MyThread2 extends Thread {
   
   ThreadController commonThreadController; 
   
   public void run() {
     synchronized(commonThreadController) {
        while (commonThreadController.currentThread != 2)
           commonThreadController.wait();

        //..... zrob cos innego

        commonThreadController.currentThread++;
        commonThreadController.notify();
     }     
   }
}


0

Dzięki, działa :)

Znalazłem praktycznie identyczny temat na tym forum, więc sorry za dubla, ale wcześniej jakoś na niego nie mogłem trafić.

import java.util.concurrent.*;

class ThreadController {
	public int currentThread = 1;
}

class A implements Runnable {

	private ThreadController commonThreadController;

	public A(ThreadController tc) {
		commonThreadController = tc;
	}

	public void run() {
		while (true) {
			synchronized (commonThreadController) {
				while (commonThreadController.currentThread != 1) {
					try {
						commonThreadController.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.print("w");
				System.out.print("a");
				System.out.print("t");
				System.out.print("e");
				System.out.print("k");
				System.out.println(" A");

				commonThreadController.currentThread = 2;
				commonThreadController.notifyAll();
			}
		}
	}
}

class B implements Runnable {

	private ThreadController commonThreadController;

	public B(ThreadController tc) {
		commonThreadController = tc;
	}

	public void run() {
		while (true) {
			synchronized (commonThreadController) {
				while (commonThreadController.currentThread != 2) {
					try {
						commonThreadController.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.print("w");
				System.out.print("a");
				System.out.print("t");
				System.out.print("e");
				System.out.print("k");
				System.out.println(" B");

				commonThreadController.currentThread = 3;
				commonThreadController.notifyAll();
			}
		}
	}
}

class C implements Runnable {

	private ThreadController commonThreadController;

	public C(ThreadController tc) {
		commonThreadController = tc;
	}

	public void run() {
		while (true) {
			synchronized (commonThreadController) {
				while (commonThreadController.currentThread != 3) {
					try {
						commonThreadController.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.print("w");
				System.out.print("a");
				System.out.print("t");
				System.out.print("e");
				System.out.print("k");
				System.out.println(" C");

				commonThreadController.currentThread = 1;
				commonThreadController.notifyAll();
			}
		}
	}
}

public class Main {
	public static void main(String[] args) {
		ThreadController threadController = new ThreadController();
		ExecutorService exec = Executors.newCachedThreadPool();
		exec.execute(new A(threadController));
		exec.execute(new B(threadController));
		exec.execute(new C(threadController));
		exec.shutdown();
	}
}
0

Witam!

Tworze gre w j2me w ktorej komputer rzuca 3 razy koscmi, po pierwszym i drugim rzucie wybiera odpowiednie do wymiany, a na koncu wybiera wynik, ktory jest najlepszy. Problemem jest wyswietlenie w/w czynnosci na ekranie, tak aby gracz mogl widziec rozgrywke CPU. Zastosowalem powyzszy sposob, faktycznie watki wykonuje pokolei (o czym swiadcza wypisywane w kolejnosci wejscia i wyjscia - System.out.println), lecz program zwraca tylko wynik, zawieszajac sie(wypisywanie w konsoli dziala, lecz nie dziala odswiezanie ekranu i blokuja sie klawisze) podczas wymiany i rzutow kosci. Czy ma ktos pomysl co jest nie tak ? Teoretycznie watki nie powinny zawieszac dzialania programu, a juz chyba z 5 sposobow rozwiazania tego problemu probowalem :/

Sama obsluga watkow wyglada nastepujaco:

    public class kontrolerWatkow{
        public int kontrola_watku=1;
    }

    public class graCpu1 extends Thread{
        
        private kontrolerWatkow kontroler;

        public graCpu1(kontrolerWatkow kw){
            kontroler=kw;
        }

        public void run(){
                synchronized(kontroler){
                    System.out.println("Wejscie watek1");
                    while(kontroler.kontrola_watku!=1){
                        try{
                            kontroler.wait();
                        }
                        catch (Exception e) {}
                    }

                    losowanie(ileKosciWymieniane());
                    pokazTabeleWynikow();
                    dokonajWyboru();
                    try{
                        this.sleep(2000);
                    }
                    catch (Exception e) {}

                    System.out.println("Wykonano watek1");

                    kontroler.kontrola_watku=2;
                    kontroler.notifyAll();
                }
            }
    }

    public class graCpu2 extends Thread{

        private kontrolerWatkow kontroler;

        public graCpu2(kontrolerWatkow kw){
            kontroler=kw;
        }

        public void run(){
                synchronized(kontroler){
                    System.out.println("Wejscie watek2");
                    while(kontroler.kontrola_watku!=2){
                        try{
                            kontroler.wait();
                        }
                        catch (Exception e) {}
                    }

                    losowanie(ileKosciWymieniane());
                    pokazTabeleWynikow();
                    dokonajWyboru();
                    try{
                        this.sleep(2000);
                    }
                    catch (Exception e) {}

                    System.out.println("Wykonano watek2");

                    kontroler.kontrola_watku=3;
                    kontroler.notifyAll();
                }
            }
    }

    public class graCpu3 extends Thread{

        private kontrolerWatkow kontroler;

        public graCpu3(kontrolerWatkow kw){
            kontroler=kw;
        }

        public void run(){
                synchronized(kontroler){
                    System.out.println("Wejscie watek3");
                    while(kontroler.kontrola_watku!=3){
                        try{
                            kontroler.wait();
                        }
                        catch (Exception e) {}
                    }

                    losowanie(ileKosciWymieniane());
                    pokazTabeleWynikow();
                    try{
                        this.sleep(2000);
                    }
                    catch (Exception e) {}
                    wyborWyniku();

                    System.out.println("Wykonano watek3");

                    kontroler.kontrola_watku=1;
                    kontroler.notifyAll();
                }
            }
    }

A uruchamiane jest to w ten sposob:

public class Rozgrywka{
    public kontrolerWatkow KontrolerWatkow=new kontrolerWatkow();
    public graCpu1 gra1=new graCpu(KontrolerWatkow);
    public graCpu2 gra2=new graCpu(KontrolerWatkow);
    public graCpu3 gra3=new graCpu(KontrolerWatkow);

    public void graj(){
        gra1.run();
        gra1.run();
        gra1.run();
    }
}
0

Chyba, ze ktos zna inny pomysl na rozwiazanie tego problemu ? :)

0

Teraz zauwazylem ... na koncu jest gra1, gra2, gra3.

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