I'm new with Java threads and I am having a few problems. I'm trying to make a simple ludo game, where each player makes their turn in a new thread. While one player is performing their turn the other threads must wait() until notified and the next player will start his turn. These threads must be synchronised so that only one thread can manipulate shared data at one time. I've implemented some basic logic but can't decide where to create the threads and if the thread logic I've implemented will work. Any help is appreciated!
Edit: I remade some parts of the code, but now I get "current thread is not owner" error after the first call of finishTurn().
Code:
Main.java:
public class Main {
public static void main(String[] args) {
Game game = new Game();
game.init();
game.run();
}
}
Game.java:
public class Game implements Runnable {
private List<Player> players;
private List<Player> fields;
private int players_finished;
private Player winner;
public Game() {
this.players = new ArrayList<>();
this.fields = new ArrayList<>();
this.players_finished = 0;
this.winner = null;
}
public void init()
{
System.out.println("Game has started!");
players.add(new Player("Magnum", this));
players.add(new Player("Felix", this));
players.add(new Player("Alex", this));
players.add(new Player("Sandra", this));
for(int i = 0; i < 20; i++) {
fields.add(i, null);
}
for(int i = 0; i < 20; i++) { // put players' 5 fields away from each other
if(i % 5 == 0)
{
fields.set(i, players.get((int)i / 5));
}
}
}
@Override
public void run()
{
List<Thread> threads = new ArrayList<>();
for(int i = 0; i < 4; i++) {
threads.add(new Thread(players.get(i)));
threads.get(i).start();
}
System.out.println("Game has started!");
finishTurn(players.get(3));
}
void finishTurn(Player player)
{
System.out.println(player + " has finished his turn!");
int i;
for(i = 0; i < players.size(); i++) {
if(players.get(i) == player) {
break;
}
}
if(i == (players.size() - 1)) {
players.get(0).notify();
}
else {
players.get(i+1).notify();
}
}
}
Player.java:
public class Player implements Runnable {
String name;
Game game;
public Player(String name, Game game) {
this.name = name;
this.game = game;
}
@Override
public void run() {
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("Player's turn has been started!");
// do other stuff
game.finishTurn(this);
}
@Override
public String toString() {
return name;
}
}