我试图为我的游戏做一台服务器,负责验证和配对。
我有一个房间的ArrayList(房间只跟踪游戏中的玩家列表),我用它来进行配对。
我有两个单身,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);
}
}
}
所以在主课程中我添加了一个新房间,仅供测试,所以房间列表至少包含一个房间。
在匹配引擎中,在run方法中,我想打印此列表的大小,但它没有,因为列表为空。
问题是我不会在任何地方清空这个列表,而且我不明白为什么它在另一个帖子中是空的。
我使用了synchronized,Collections.synchronizedList,甚至是ConcurrentMap进行测试,没有工作......
我怎样才能确定该列表是否真的是线程安全的,并且没有任何理由不清空?
答案 0 :(得分:2)
brew install gcc
不是单身人士:
PoulpiciousServer
类PoulpiciousServerHolder
方法您只能在PoulpiciousServer.main
方法中创建的内容上调用PoulpiciousServer.run()
。
您可以访问由main
返回的实例中的房间列表,PoulpiciousServer.get()
类是由PoulpiciousServerHolder
类创建的实例。这个从未添加任何房间,因为它的run()
方法永远不会被调用。
将new PoulpiciousServer()
方法中的main
替换为PoulpiciousServer.get()
。