2016-03-28 2 views
2

Я пытаюсь сделать сервер для своей игры, ответственный за аутентификацию и сватовство.ArrayList пуст в другой теме

У меня есть ArrayList of Rooms (номера просто отслеживают список игроков в игре), которые я использую для сватовства.

У меня есть два синглета, PoulpiciousServer.java, который является основным классом, который запускает все, и MatchmakingEngine, который запускается в другом потоке и обрабатывает игроков, требующих комнаты для игры.

Вот классы (я использую KryoNet):

package com.poulpicious.server; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

import com.esotericsoftware.kryo.Kryo; 
import com.esotericsoftware.kryonet.Connection; 
import com.esotericsoftware.kryonet.Server; 
import com.poulpicious.network.packets.Packet00Login; 
import com.poulpicious.network.packets.Packet01LoginAcknowledge; 
import com.poulpicious.network.packets.Packet02CharacterInfos; 
import com.poulpicious.network.packets.Packet03CharacterInfosResponse; 
import com.poulpicious.network.packets.Packet04RequestMatchmaking; 
import com.poulpicious.network.packets.Packet05MatchmakingResponse; 
import com.poulpicious.network.packets.Packet06StopMatchmaking; 

public class PoulpiciousServer { 

    private static class PoulpiciousServerHolder { 
     private static final PoulpiciousServer _instance = new PoulpiciousServer(); 
    } 

    public static PoulpiciousServer get() { 
     return PoulpiciousServerHolder._instance; 
    } 

    private Server server; 

    private Map<Integer, ServerPlayer> serverPlayers = new HashMap<Integer, ServerPlayer>(); 
    private List<Room> rooms; 

    private Thread matchmakingEngineThread; 

    public PoulpiciousServer() { 
     this.server = new Server(); 
     this.rooms = Collections.synchronizedList(new ArrayList<Room>()); 

     Kryo k = this.server.getKryo(); 
     k.register(Packet00Login.class); 
     k.register(Packet01LoginAcknowledge.class); 
     k.register(Packet02CharacterInfos.class); 
     k.register(Packet03CharacterInfosResponse.class); 
     k.register(Packet04RequestMatchmaking.class); 
     k.register(Packet05MatchmakingResponse.class); 
     k.register(Packet06StopMatchmaking.class); 
    } 

    public void run() { 
     try { 
      this.rooms.add(new Room()); 
      server.addListener(new PoulpiciousServerListener(this)); 

      this.matchmakingEngineThread = new Thread(MatchmakingEngine.get(), "matchmaking"); 
      this.matchmakingEngineThread.start(); 

      server.start(); 
      server.bind(25565, 25565); 

      System.out.println("Master server started."); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void registerPlayer(Connection c, String username) { 
     this.serverPlayers.put(c.getID(), new ServerPlayer(c, username)); 
    } 

    public static void main(String[] args) { 
     new PoulpiciousServer().run(); 
    } 

    public ServerPlayer getServerPlayer(int connID) { 
     return this.serverPlayers.get(connID); 
    } 

    public Room getRoom(int index) { 
     synchronized (rooms) { 
      return this.rooms.get(0); 
     } 
    } 

    public List<Room> getRooms() { 
     return rooms; 
    } 

} 

И сватовство двигатель:

package com.poulpicious.server; 

import java.util.ArrayList; 

import com.poulpicious.network.packets.Packet05MatchmakingResponse; 

public class MatchmakingEngine implements Runnable { 

    private static class MatchmakingEngineHolder { 
     private static final MatchmakingEngine _instance = new MatchmakingEngine(); 
    } 

    public static MatchmakingEngine get() { 
     return MatchmakingEngineHolder._instance; 
    } 

    private boolean running; 

    private ArrayList<ServerPlayer> playersSearching = new ArrayList<ServerPlayer>(); 

    public MatchmakingEngine() { 
     this.running = true; 
    } 

    @Override 
    public void run() { 
     while (running) { 
      if (PoulpiciousServer.get().getRooms().size() > 0) 
       System.out.println(PoulpiciousServer.get().getRooms().size()); 

      synchronized (playersSearching) { 
       // System.out.println(playersSearching.size()); 
       if (playersSearching.size() > 0) { 
        System.out.println("Matching a player"); 
        ServerPlayer current = playersSearching.get(0); 

        PoulpiciousServer.get().getRoom(0).addPlayer(current); 

        Packet05MatchmakingResponse pmr = new Packet05MatchmakingResponse(); 
        pmr.nbPlayers = PoulpiciousServer.get().getRoom(0).getPlayerCount(); 
        current.getConnection().sendTCP(pmr); 
        playersSearching.remove(0); 
       } 
      } 
     } 
    } 

    public void registerPlayer(ServerPlayer player) { 
     synchronized (playersSearching) { 
      this.playersSearching.add(player); 
     } 
    } 

} 

Таким образом, в главном классе я добавить новый номер, только для тестирования, так что номер в номере содержит не менее 1 комнаты.

В движке matchmaking, в методе run, я хочу напечатать размер этого списка, но это не так, потому что список пуст.

Проблема в том, что я не опустошаю этот список в любом месте, и я не понимаю, почему он пуст в другом потоке.

я использовал синхронизированный, Collections.synchronizedList, даже ConcurrentMap для тестирования, никто не работал ...

Как я могу быть уверен, что список действительно потокобезопасный и не опорожняется без причины?

+2

Когда вы пишете 'new PoulpiciousServer(). Run()' в своем 'main' методе, почему вы не используете' PoulpiciousServer.get(). Run() '? Неужели «PoulpiciousServer» не является синглом? –

+0

О, мой бог ... Спасибо .. –

ответ

2

PoulpiciousServer не одноэлементно:

  • Вы создаете один экземпляр в PoulpiciousServerHolder класса
  • Вы создаете один экземпляр в методе PoulpiciousServer.main

Вы только позвоните PoulpiciousServer.run() по созданному в методе main.

Вы получаете доступ к списку комнат в экземпляре, возвращаемом PoulpiciousServer.get(), который является экземпляром, созданным классом PoulpiciousServerHolder. В этом никогда не было добавлено никаких комнат, так как его метод run() никогда не вызывается.

Заменить использование new PoulpiciousServer() в вашем методе main с помощью PoulpiciousServer.get().

+0

Я изменил его, и это сработало. Я действительно этого не видел! Большое спасибо. –

Смежные вопросы