Hi all :) Sorry for this really long question but this needs some explaination.
I was given an assignment where i have to turn a very simple game into a 2 player multiplayer game. The reason why we have to make this game is to learn more about threads and concurrency. I have never worked with concurrency nor with multiple threads.
My idea is to create a TCP server like i have done in GameServer.java where i create a new ServiceObject for each player. I create a thread for each ServiceObject where i will recieve, handle and send commands from a client.
Gameserver.java
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class GameServer {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(6789);
        System.out.println("Waiting for clients to connect . . . ");
        Socket s1 = server.accept();
        System.out.println("Clients connected.");
        PlayerService servicep1 = new PlayerService(s1);
        Thread t1 = new Thread(servicep1);
        Socket s2 = server.accept();
        System.out.println("Clients connected.");
        PlayerService servicep2 = new PlayerService(s2);
        Thread t2 = new Thread(servicep2);
        t1.start();
        t2.start();
        servicep1.sendDataToClient("ready");
        servicep2.sendDataToClient("ready");
    }
}
PlayerService.java
package server;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingQueue;
import game2016.Player;
public class PlayerService extends Thread {
    private Socket s;
    private PlayerService opponent;
    private Scanner in;
    private PrintWriter out;
    public PlayerService(Socket aSocket) {
        this.s = aSocket;
    }
    public void setOpponent(PlayerService opponent) {
        this.opponent = opponent;
    }
    public void run() {
        try {
            in = new Scanner(s.getInputStream());
            out = new PrintWriter(s.getOutputStream());
            try {
                doService();
            } finally {
//              s.close();
            }
        } catch (IOException exception) {
            exception.printStackTrace();
        }
    }
    public void doService() throws IOException {
        while (true) {
            if (!in.hasNext()) {
                return;
            }
            String command = in.next();
            if (command.equals("QUIT")) {
                return;
            } else
                recieveFromClient(command);
        }
    }
    public void recieveFromClient(String command) throws IOException {
        System.out.println(command);
        if(command.equals("player")) {
            String newPlayerName = in.next();
            int xPos = in.nextInt();
            int yPos = in.nextInt();
            String direction = in.next();
//          sendDataToOpponent("addOpponent " + newPlayerName + " " + xPos + " " +  yPos + " " + direction);
        } 
    }
    public void sendDataToClient(String response) {
        out.write(response + "\n");
        out.flush();
    }
    public void sendDataToOpponent(String response) {
        opponent.sendDataToClient(response);
    }
    }
To send data from one client to another client i have a reference to the opponents servicelayer as i can invoke the sendDataToOpponent() method to send data to him and if the server have to communicate i can just invoke sendDataToClient() from the server.
My problem is that i want to postpone opening my clients GUI to both clients have connected.
Main.java(Client) - GUI code have been left out
private static Socket s;
private static InputStream instream;
private static OutputStream outstream;
private static Scanner in;
private static PrintWriter out;
private static boolean isOpponentConnected;
public static void main(String[] args) throws Exception {
    openConnection();
    reciever();
    waitOpponentConected();
    launch(args);
}
public static void waitOpponentConected() throws Exception {
    while(!isOpponentConnected) {
        System.out.println("Waiting for opponent");
        Thread.sleep(2000);
    }
    System.out.println("Opponent is ready now");
}
public static void openConnection() throws IOException {
    s = new Socket("localhost", 6789);
    System.out.println("Connection established");
    instream = s.getInputStream();
    outstream = s.getOutputStream();
    in = new Scanner(instream);
    out = new PrintWriter(outstream);
}
public static void responseFromServer() throws IOException {
     try {
         while(in.hasNext()) {
                String response = in.next();
                if(response.equals("ready")) {
                    isOpponentConnected = true;
                    System.out.println("Ready");
                } 
         }
        } catch (Exception e) {
        }
 }
public static void reciever() {
    Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            while(true) {
                responseFromServer();
            }
        }
    };
    new Thread(task).start();
}
public static void sendCommandToServer(String command) throws IOException {
    out.print(command + "\n");
    out.flush();
}
I've created a Thread to recieve commands from the server, and when both clients have connected to the server it sends a string 'ready' to each of the clients. My thought was that The Main-thread sleeps till isOpponentConnected is true.
But my gameserver fails and prints out a nullpointer exception when the second clients connects to the server. I've spend to days reading and trying to fix this bug. When i run the code in debug mode, both clients recieves the ready signal and the GUI starts for both clients.
Exception in thread "main" java.lang.NullPointerException
    at server.PlayerService.sendDataToClient(PlayerService.java:67)
    at server.GameServer.main(GameServer.java:23)
Can you guys see anything i'm obviously doing wrong?
I think this queston is interesseting because it's not just the nullpointerexception, it's about structering TCP server-client relationships and the chain when things are initialized and ready when threads and connections are made.
 
    