Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.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 多线程问题-在线程之间传递对象_Java_Multithreading_Lwjgl_Packet - Fatal编程技术网

Java 多线程问题-在线程之间传递对象

Java 多线程问题-在线程之间传递对象,java,multithreading,lwjgl,packet,Java,Multithreading,Lwjgl,Packet,我目前正在尝试用java(使用OpenGL(LWJGL))制作一个非常简单的多人游戏,目前该程序运行在两个不同的线程上 线程1:运行所有游戏逻辑和渲染 线程2:处理服务器和客户端之间的连接 因此,线程2基本上会坐着等待传入的数据包,每当它收到登录数据包时,我希望它创建一个播放器对象,但新对象似乎是在线程2上创建的,在尝试渲染时会导致以下错误: 线程“thread-2”java.lang.IllegalStateException中的异常:未为当前线程设置任何GLCapabilities实例。 我

我目前正在尝试用java(使用OpenGL(LWJGL))制作一个非常简单的多人游戏,目前该程序运行在两个不同的线程上

线程1:运行所有游戏逻辑和渲染

线程2:处理服务器和客户端之间的连接

因此,线程2基本上会坐着等待传入的数据包,每当它收到登录数据包时,我希望它创建一个播放器对象,但新对象似乎是在线程2上创建的,在尝试渲染时会导致以下错误:

线程“thread-2”java.lang.IllegalStateException中的异常:未为当前线程设置任何GLCapabilities实例。

我对OpenGL和多线程都比较陌生,可能有一个非常简单明了的解决方案,但我想知道如何在接收数据包时创建一个对象并将其添加到线程1中

线程2:

public void run() {
    while (running) {
        byte[] data = new byte[1024];
        DatagramPacket packet = new DatagramPacket(data, data.length);
        try {
            socket.receive(packet);
        } catch (IOException e) {
            e.printStackTrace();
        }
        parsePacket(packet.getData(), packet.getAddress(), packet.getPort());
        }
    }
parsePacket()检查数据包的类型,如果是登录数据包,它将调用以下方法:

public void addPlayerToGame(byte[] data, InetAddress address, int port) {
    Packet00Login packet = new Packet00Login(data);

    level.addObject(new PlayerMP(packet.getUsername(), new Vector3f(0.0f, 0.0f, 0.0f), address, port));
} 
addObject方法只是将对象添加到arraylist中

public void addObject(GameObject o) {
    this.objects.add(o);
}
然后在线程1上使用此调用渲染所有对象:

public void render() {
    for (GameObject o : objects) {
        o.render();
    }
    player.render();
}

你不应该从第二个线程修改你的游戏对象列表,因为变化非常大,你将在第一个线程中迭代该列表。这将导致当前修改异常。更糟糕的是,使用openGL创建未定义的行为

你要做的是在你的第一个线程上有一个任务列表。在每个循环中,执行任务列表中的所有任务,然后清除它

因此,不要直接将游戏对象添加到列表中,而是添加一个任务来添加对象


(同时,确保任务的执行是线程安全的)

显示(至少)
PlayerMP
的构造函数和堆栈跟踪的相关部分。很可能,您正在构造函数中执行GL操作,而这发生在错误的线程上。然后,解决方案可能是将创建播放器所需的信息处理到GL线程,并让GL线程实际创建播放器。@Marco13是的,我在构造函数中调用了GL操作!在将对象添加到列表(在GL线程上)之前,我将所有这些操作移动到一个“prepare”方法中,并调用该方法,现在它可以工作了!谢谢你的帮助!:)我制作了一个单独的数组列表,在其中我添加了所有应该添加的内容,然后遍历它!很有魅力,谢谢!:)在我看来,你无论如何都应该有一份任务清单。因为你可能需要在某个时刻(比如当玩家移动时)更新当前列表中的对象,而拥有另一个列表对你没有帮助。还有,别忘了验证答案啊,那是真的!我以前从未做过这样的事情,我感谢所有能得到的帮助。我一定会调查的,谢谢:)