Questo è il server!!
codice:
package jcallremember.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 *
 * @author Linux
 */
public class ServerListener implements Runnable {


    private final Thread ascoltatore;
    private final Thread verificaChiusura;
    private  volatile boolean richiestaChiusura;
    private final ServerSocket socketListen;
    private final ArrayList<ServerWorker> arrayServer;
    private final long id_ascoltatore;
    private final long id_verificaChiusura;
    private final ReentrantLock lock;
    private final Condition condizione;


    public  boolean isRichiestaChiusura() {
        return richiestaChiusura;
    }


    public void requestClose() {
       richiestaChiusura = true;
    }


    public ServerListener(ReentrantLock L, Condition C) throws IOException {
        ascoltatore = new Thread(this);
        verificaChiusura = new Thread(this);
        id_ascoltatore = ascoltatore.getId();
        id_verificaChiusura = verificaChiusura.getId();
        socketListen = new ServerSocket(40000, 50);
        arrayServer = new ArrayList<>();
        this.lock = L;
        this.condizione = C;


    }


    public void verificaConnessione() throws IOException {
        try{
            Socket socketAccept = socketListen.accept();
            ServerWorker sW = new ServerWorker(socketAccept);
            sW.start();
            
            this.arrayServer.add(sW);


        } catch(java.net.SocketException ex){
           Thread.currentThread().interrupt();
       }
        
    }


    public void start() {
        this.verificaChiusura.start();
        this.ascoltatore.start();
    }


    @Override
    public void run() {
        if (Thread.currentThread().getId() == this.id_ascoltatore) {
            try {
                this.verificaConnessione();
            } catch (IOException ex) {
                Logger.getLogger(ServerListener.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
        } else if (Thread.currentThread().getId() == this.id_verificaChiusura) {
            this.lock.lock();


            try {
                while (!isRichiestaChiusura()) {
                    this.condizione.await();
                }
                
                this.socketListen.close();
                
                for(ServerWorker sw:this.arrayServer){
                    synchronized(sw){
                    sw.requestClose();
                    sw.notify();
                    }
                }
            }catch (InterruptedException | IOException  ex) {
                Logger.getLogger(ServerListener.class.getName()).
                        log(Level.SEVERE, null, ex);
            }finally {
                this.lock.unlock();
            }
        }


    }
}