Java ArrayList在另一个线程中为空
我正在尝试为我的游戏做一个服务器,负责身份验证和配对 我有一个房间列表(房间只记录游戏中的玩家列表),我用它来配对 我有两个单例,poulpicusserver.java是主类,它运行所有的东西,还有MatchmakingEngine,它运行在另一个线程上,处理玩家请求房间玩的问题 以下是类(我使用KryoNet):Java ArrayList在另一个线程中为空,java,multithreading,list,Java,Multithreading,List,我正在尝试为我的游戏做一个服务器,负责身份验证和配对 我有一个房间列表(房间只记录游戏中的玩家列表),我用它来配对 我有两个单例,poulpicusserver.java是主类,它运行所有的东西,还有MatchmakingEngine,它运行在另一个线程上,处理玩家请求房间玩的问题 以下是类(我使用KryoNet): package com.poulpicious.server; 导入java.io.IOException; 导入java.util.ArrayList; 导入java.util.
package com.poulpicious.server;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入com.esotericsoftware.kryo.kryo;
导入com.esotericsoftware.kryonet.Connection;
导入com.esotericsoftware.kryonet.Server;
导入com.poulpicious.network.packets.Packet00Login;
导入com.poulpicious.network.packets.Packet01LoginAcknowledge;
导入com.poulpicious.network.packets.packet02characterInfo;
导入com.poulpicious.network.packets.packet03字符信息响应;
导入com.poulpicious.network.packets.packet04请求匹配;
导入com.poulpicious.network.packets.Packet05MatchmakingResponse;
导入com.poulpicious.network.packets.packet06停止匹配;
公共类poulpiousserver{
私有静态类PoulpiciousServerHolder{
私有静态最终PoulPiousServer_实例=新PoulPiousServer();
}
公共静态poulpiousserver get(){
返回POULPICOUSSERVERHOLDER.\u实例;
}
专用服务器;
私有映射服务器players=newhashmap();
私人名单室;
私有线程匹配引擎线程;
公共poulpiousserver(){
this.server=新服务器();
this.rooms=Collections.synchronizedList(新的ArrayList());
kryok=this.server.getKryo();
k、 注册(Packet00Login.class);
k、 注册(Packet01LoginAcknowledge.class);
k、 寄存器(packet02characterinfo.class);
k、 寄存器(Packet03CharacterInfosResponse.class);
k、 寄存器(Packet04RequestMatchmaking.class);
k、 寄存器(Packet05MatchmakingResponse.class);
k、 注册(packet06stopmaching.class);
}
公开募捐{
试一试{
此.rooms.add(新房间());
addListener(新的PoulpiousServerListener(this));
this.matchmakingEngineThread=新线程(MatchmakingEngine.get(),“matchmaking”);
这个.matchmakingEngineThread.start();
server.start();
绑定(25565,25565);
System.out.println(“主服务器已启动”);
}捕获(IOE异常){
e、 printStackTrace();
}
}
public void registerPlayer(连接c,字符串用户名){
this.serverPlayers.put(c.getID(),新的ServerPlayer(c,用户名));
}
公共静态void main(字符串[]args){
新建PoulPiousServer().run();
}
公共服务器播放器getServerPlayer(int-connID){
返回此.serverPlayers.get(connID);
}
公共休息室(内部索引){
同步(房间){
返回此.rooms.get(0);
}
}
公共列表getRooms(){
返回室;
}
}
以及配对引擎:
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);
}
}
}
package com.poulpicious.server;
导入java.util.ArrayList;
导入com.poulpicious.network.packets.Packet05MatchmakingResponse;
公共类MatchmakingEngine实现Runnable{
私有静态类MatchmakingEngineHolder{
私有静态最终MatchmakingEngine_实例=新MatchmakingEngine();
}
公共静态匹配引擎get(){
返回MatchmakingEngineHolder.\u实例;
}
私有布尔运行;
private ArrayList playersSearching=新建ArrayList();
公共MatchmakingEngine(){
这是真的;
}
@凌驾
公开募捐{
(跑步时){
if(poulpicusserver.get().getRooms().size()>0)
System.out.println(poulpicusserver.get().getRooms().size());
已同步(播放机搜索){
//System.out.println(playersSearching.size());
如果(PlayerSearching.size()>0){
System.out.println(“匹配玩家”);
ServerPlayer current=playerssearch.get(0);
poulpicusserver.get().getRoom(0).addPlayer(当前);
Packet05MatchmakingResponse pmr=新Packet05MatchmakingResponse();
pmr.nbPlayers=poulpicusserver.get().getRoom(0.getPlayerCount();
current.getConnection().sendTCP(pmr);
播放搜索。删除(0);
}
}
}
}
公共无效注册层(服务器播放器){
已同步(播放机搜索){
this.playerssearch.add(player);
}
}
}
所以在主类中,我添加了一个新房间,只是为了测试,所以房间列表至少包含一个房间
在匹配引擎中的run方法中,我想打印这个列表的大小,但它没有打印,因为列表是空的
问题是我没有在任何地方清空这个列表,我不明白为什么在另一个线程中它是空的
我使用synchronized、Collections.synchronizedList,甚至ConcurrentMap进行测试,都不起作用
如何确保列表是真正线程安全的,并且不会无故清空?
poulpicusserver
不是单例:
- 您可以在
类中创建一个实例poulpiousserverholder
- 您可以在
方法中创建一个实例poulpiousserver.main
main
方法中创建的方法调用poulpiousserver.run()
您可以访问由poulpiousserver.get()
返回的实例中的文件室列表,这是ins
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);
}
}
}