Threads wait wird nicht durch notify beendet!

mrbig2017

Mitglied
Eine einfache Cyclic Barrier Kodierung mit Absicht ohne die Java Klasse!
Sources auch nochmal hier:
https://openload.co/f/M2dX_d-2juc/CPlayers.java
https://openload.co/f/f98nYLqAXKE/TestCyclicBarrier.java


public class TestCyclicBarrier
{
//Main Thread
public static void main(String[] args)
{
final int noOfPlayers=3;
//Neues Array/Feld von Threads
Thread[] trdPlayer = new Thread[noOfPlayers];

for (int i = 0; i < noOfPlayers; i++) {
// Für das neu erzeugte Array müssen wir in JEDEM Element Speicher für die Klasse reservieren!
CPlayers clsPlayer = new CPlayers(noOfPlayers);
// Klasse zufügen
trdPlayer = new Thread(clsPlayer);
// Namen auf Nr. setzen
trdPlayer.setName(String.valueOf(i+1));
// Thread starten
trdPlayer.start();
}
}

import java.util.*;
class CPlayers implements Runnable
{
static int noOfPlayersReady=0; // Aktuelle Anzahl der Spieler, die spielbereit sind
private int minNoOfPlayers; // Anzahl der Spieler um Spiel zu beginnen
//**************************************************************************************************
// Konstruktor
// int minNoOfPlayers: Anzahl der Spieler, die für den Spielstart nötig sind
//**************************************************************************************************
CPlayers(int minNoOfPlayers){
this.minNoOfPlayers=minNoOfPlayers;
}

//**************************************************************************************************
// Startet den Thread
//**************************************************************************************************
@Override
public void run()
{
// Zufallszahl bestimmen
Random rndNumber = new Random();
// Simuliert das Warten zwischen 1,2,3,4,5 Sekunden
try {
// berechnet eine Zufallszahl zwischen 1000 und 5000; Inkrement 1000
int myWaitTillReadyTime=1000*(rndNumber.nextInt(5)+1);
System.out.println("Player No "+Thread.currentThread().getName()+": Ready to start in "+myWaitTillReadyTime+" seconds!");
// Legt den Thread schlafen: Zeit, die der Spieler zum Spielstart braucht
Thread.currentThread().sleep(myWaitTillReadyTime);
} catch(Exception e) {
System.out.println(Thread.currentThread().getName()+ " error in sleeping!");
}
// Anzahl der bereiten Spieler erhöhen
noOfPlayersReady++;
// Solange noch nicht alle Spieler bereit sind
while (noOfPlayersReady<minNoOfPlayers) {
// Berechne die Anzahl der Spieler, auf die wir warten und gibt dies mit dem Spielernamen aus
int noOfPlayersToWait=minNoOfPlayers-noOfPlayersReady;
System.out.println("Player No "+Thread.currentThread().getName()+ " is waiting for "+noOfPlayersToWait+ " Players!");
// Lege den Thread kurz auf "Eis", auch damit nicht zu viele Bildschirmausgaben erfolgen
try {
Thread.currentThread().sleep(100);
} catch(Exception e) {
System.out.println(Thread.currentThread().getName()+ " error in sleeping!");
}
} // end of while
// Yeah....alle bereit....wir dürfen starten!!
System.out.println(Thread.currentThread().getName()+ " has started because "+noOfPlayersReady+" Players are ready!");
}
}

Wie bereits gesagt....das notifyAll löst nicht das wait auf....warum?
 
Sorry....falsche Version...diese hier ist richtig:
import java.util.*;
class CPlayers implements Runnable
{
static int noOfPlayersReady=0; // Aktuelle Anzahl der Spieler, die spielbereit sind
private int minNoOfPlayers; // Anzahl der Spieler um Spiel zu beginnen
//**************************************************************************************************
// Konstruktor
// int minNoOfPlayers: Anzahl der Spieler, die für den Spielstart nötig sind
//**************************************************************************************************
CPlayers(int minNoOfPlayers){
this.minNoOfPlayers=minNoOfPlayers;
}

//**************************************************************************************************
// Startet den Thread
//**************************************************************************************************
@Override
public void run()
{
// Zufallszahl bestimmen
Random rndNumber = new Random();
// Simuliert das Warten zwischen 1,2,3,4,5 Sekunden
try {
// berechnet eine Zufallszahl zwischen 1000 und 5000; Inkrement 1000
int myWaitTillReadyTime=1000*(rndNumber.nextInt(2)+1);
System.out.println("Player No "+Thread.currentThread().getName()+": Ready to start in "+myWaitTillReadyTime+" seconds!");
// Legt den Thread schlafen: Zeit, die der Spieler zum Spielstart braucht
Thread.currentThread().sleep(myWaitTillReadyTime);
} catch(Exception e) {
System.out.println(Thread.currentThread().getName()+ " error in sleeping!");
}
// Anzahl der bereiten Spieler erhöhen
noOfPlayersReady++;
// Solange noch nicht alle Spieler bereit sind: Thread soll warten
synchronized (this){
if (noOfPlayersReady<minNoOfPlayers) {
// Berechne die Anzahl der Spieler, auf die wir warten und gibt dies mit dem Spielernamen aus
int noOfPlayersToWait=minNoOfPlayers-noOfPlayersReady;
System.out.println("Player No "+Thread.currentThread().getName()+ " is waiting for "+noOfPlayersToWait+ " Players!"+noOfPlayersReady);
try {
this.wait();
} catch(Exception e) {
e.printStackTrace();
//System.out.println("Player No "+Thread.currentThread().getName()+ " is not amused 2 wait :-(");
}
System.out.println("The wait is over!");
}
// noOfPlayersReady = minNoOfPlayers: Alle da!!!
else {
System.out.println("Yeah...we r complete! Let's start!");
this.notifyAll();
}
}
// Yeah....alle bereit....wir dürfen starten!!
System.out.println(Thread.currentThread().getName()+ " has started because "+noOfPlayersReady+" Players are ready!");
}
}
 
Wenn ich’s richtig sehe, nutzen alle als Monitor this, und bekommen daher nichts von den anderen mit. Du solltest über ein gemeinsames Objekt synchronisieren
 

Zurück
Oben