Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ArrayList在另一个线程中为空_Java_Multithreading_List - Fatal编程技术网

Java ArrayList在另一个线程中为空

Java ArrayList在另一个线程中为空,java,multithreading,list,Java,Multithreading,List,我正在尝试为我的游戏做一个服务器,负责身份验证和配对 我有一个房间列表(房间只记录游戏中的玩家列表),我用它来配对 我有两个单例,poulpicusserver.java是主类,它运行所有的东西,还有MatchmakingEngine,它运行在另一个线程上,处理玩家请求房间玩的问题 以下是类(我使用KryoNet): package com.poulpicious.server; 导入java.io.IOException; 导入java.util.ArrayList; 导入java.util.

我正在尝试为我的游戏做一个服务器,负责身份验证和配对

我有一个房间列表(房间只记录游戏中的玩家列表),我用它来配对

我有两个单例,poulpicusserver.java是主类,它运行所有的东西,还有MatchmakingEngine,它运行在另一个线程上,处理玩家请求房间玩的问题

以下是类(我使用KryoNet):

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);
        }
    }

}