2017-12-05 8 views
0

Ich versuche, zwei Threads in der gleichen Zeit zu arbeiten. Lassen Sie mich mit dem Code erklären:Zwei Threads gleichzeitig ausführen (Multithreading?)

Hauptklasse, die beiden Fäden laufen

public static void main(String[] args) { 
    abThread.move(5); 
    cdThread.move(5); 
} 

Gewinde 1:

static void move(int i) { 
    int min = 0; 
    int max = 100; 

    while (i > 0) { 
     int a = ThreadLocalRandom.current().nextInt(min, max + 1); 
     // try { 
     //  Thread.sleep(100); 
     // } catch (Exception e) { 
     // } 

     if ((a % 2) == 1) { 
      System.out.println("a"); 
      i -= 1; 
      continue; 
     } else { 
      System.out.println("b"); 
      i -= 1; 
      continue; 
     } 
    } 
} 

Thema 2:

static void move(int i) { 
    int min = 0; 
    int max = 100; 

    while (i > 0) { 
     int a = ThreadLocalRandom.current().nextInt(min, max + 1); 
     // try { 
     //  Thread.sleep(100); 
     // } catch (Exception e) { 
     // } 

     if ((a % 2) == 1) { 
      System.out.println("c"); 
      i -= 1; 
      continue; 
     } else { 
      System.out.println("d"); 
      i -= 1; 
      continue; 
     } 
    } 
} 

Im immer zufällig a/bx 5 und nach 5 von ihnen bin ich zufällig (c/d) x5

Mein Ziel ist es, a/b, c/d, a/b, c/d ... und so weiter

Jede Hilfe oder Weiterleitung zu irgendeinem Weg - würde es sehr schätzen!

Edit: Beachten Sie, ich versuchte mit versuchen, Schlaf, aber es verschiebt nur, wie lange vor dem nächsten a/b nach a/b. Nur so konnte ich es a/b, c/b

abThread.move(1); 
    cdThread.move(1); 
    abThread.move(1); 

......

Dank

+3

Sie erscheinen alle Arbeiten in Ihrem Haupt-Thread zu tun, und keiner in den dargestellten Themen von 'abThread 'und' cdThread'. Das Aufrufen einer Methode für eine 'Thread'-Instanz führt nicht dazu, dass die Arbeit im Ausführungsthread ausgeführt wird, der von diesem Objekt dargestellt wird. –

+0

Ja, irgendeine Idee, Richtung? :) – joe123

Antwort

-1

Die Fäden laufen in ihrem eigenen Tempo wäre, auf geplante immer und ausschalten die CPU wie das Betriebssystem wünscht. Sie können nur erwarten, a/b, c/d, a/b, c/d, ... Ausführung zu erhalten, wenn das Betriebssystem Round-Robin-Scheduling verwendet (d. H. Jeder Thread erhält eine Runde, in einem Kreis), die es fast sicher nicht tut.

+0

Ja, aber es sieht nicht so aus, dass das Hauptproblem des OP ist. –

+0

@JohnBollinger Ja, ich habe deinen Kommentar bemerkt. Aber selbst wenn diese Methoden auf separaten Threads laufen, würde er immer noch nicht a/b, c/d, a/b, c/d, ... bekommen. – Alexander

+0

Also gibt es eine Problemumgehung, die du mir nicht empfehlen solltest ? – joe123

0

Die Arbeit von einem anderen Thread als die wichtigsten ausgeführt wird durch die Runnable bestimmt, mit dem sie initialisiert wurde oder durch die Umsetzung ihrer run() Methode, wenn Sie, dass außer Kraft gesetzt haben. Einer dieser Orte ist, wo Sie die Aufrufe der verschiedenen move() Methoden platzieren sollten. Dann sollte Ihr Haupt-Thread start() beide Thread-Instanzen.

Dies (wahrscheinlich) erreicht die Threads, die parallel laufen, abhängig von der Thread-Planung und der Verfügbarkeit von Ausführungsressourcen. Wie @Alexander beschrieben hat, erzeugt es jedoch nicht unbedingt einen perfekten Wechsel zwischen den Ausgaben der beiden Threads, noch garantiert es sogar, dass irgendeine der von einem Thread erzeugten Ausgabe vor irgendeiner der von der anderen erzeugten Ausgabe erscheint.

Wenn Sie einen perfekten Wechsel benötigen, müssen die beiden Threads miteinander synchronisiert werden, um sich zu abwechseln. Es gibt eine Vielzahl von Möglichkeiten, die Sie implementieren können, aber wenn Sie es wollen, muss es in Ihre move() Methoden eingebaut werden. Die Low-Level-, Old-School-Wege drehen sich um die Verwendung der wait() und notify()/notifyAll() Methoden eines gemeinsamen Objekts. Sie können auch eine SynchronousQueue für nur zwei Threads verwenden, die sich neben vielen anderen Möglichkeiten abwechseln.

+0

Vielen Dank für die sparsame Zeit zu erarbeiten. Ich schätze es! – joe123

0

Wenn Sie wirklich mit Threads experimentieren wollen, nicht nur Druckzeichen abwechselnd, könnten Sie so etwas wie dies versuchen:

Zu allererst Runnable implementieren, die Code von Threads ausgeführt werden gilt:

class Task implements Runnable { 
    //c1 and c2 are characters to print (a,b and c,d for example) 
    private final String c1, c2; 
    //semaphore guarantees the order of threads execution 
    private final Semaphore sync; 
    private int i; 

    Task(int i, String c1, String c2, Semaphore sync) { 
     this.i = i; 
     this.c1 = c1; 
     this.c2 = c2; 
     this.sync = sync; 
    } 
    @Override 
    public void run() { 
     try { 
      int min = 0; 
      int max = 100; 
      while (i > 0) { 
       sync.acquire(); 
       int a = ThreadLocalRandom.current().nextInt(min, max + 1); 
       if ((a % 2) == 1) { 
        System.out.println(c1); 
        i -= 1; 
       } else { 
        System.out.println(c2); 
        i -= 1; 
       } 
       sync.release(); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

    } 
} 

Dann erstellen Semaphore:

Semaphore sync = new Semaphore(0, true); 

zwei Threads erstellen und führen sie sie:

Thread t1 = new Thread(new Task(10, "a", "b", sync)); 
Thread t2 = new Thread(new Task(10, "c", "d", sync)); 

t1.start(); 
t2.start(); 

Und schließlich Semaphore freizugeben, so dass einer der Threads auf sie warten fortfahren können:

sync.release(); 
Verwandte Themen