多线程问题 - 在线程之间传递对象
Multi-threading Issue - Passing objects between threads
我目前正尝试在 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 方法只是将对象添加到数组列表中。
public void addObject(GameObject o) {
this.objects.add(o);
}
然后在线程 1 上使用此调用呈现所有对象:
public void render() {
for (GameObject o : objects) {
o.render();
}
player.render();
}
你不应该从第二个线程修改你的游戏对象列表,因为变化非常大,你将在第一个线程中迭代该列表。这将导致当前修改异常。或者更糟,使用 openGL 创建未定义的行为。
您需要做的是在您的第一个线程上有一个任务列表。每次循环,执行任务列表中的所有任务,然后清除它。
所以不是直接将游戏对象添加到列表中,而是添加一个任务来添加对象。
(另外,确保任务的执行线程安全)
我目前正尝试在 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 方法只是将对象添加到数组列表中。
public void addObject(GameObject o) {
this.objects.add(o);
}
然后在线程 1 上使用此调用呈现所有对象:
public void render() {
for (GameObject o : objects) {
o.render();
}
player.render();
}
你不应该从第二个线程修改你的游戏对象列表,因为变化非常大,你将在第一个线程中迭代该列表。这将导致当前修改异常。或者更糟,使用 openGL 创建未定义的行为。
您需要做的是在您的第一个线程上有一个任务列表。每次循环,执行任务列表中的所有任务,然后清除它。
所以不是直接将游戏对象添加到列表中,而是添加一个任务来添加对象。
(另外,确保任务的执行线程安全)