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

时间:2016-03-20 14:44:10

标签: java multithreading lwjgl packet

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

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

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

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

线程中的异常"线程-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();
}

1 个答案:

答案 0 :(得分:0)

您不应该从第二个线程修改GameObject列表,因为更改非常高,您将在第一个线程中对该列表进行迭代。哪会导致当前修改异常。或者更糟糕的是,使用openGL创建未定义的行为。

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

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

(另外,确保执行任务线程安全)