我的问题是,对于特定情况,交错多个 ReentrantLocks 是否是一个相当有效的选择:3D 空间中的相机移动(LWJGL,openGL)——当然是图形表示。
我的相机控制器对象拥有一个私有方法来操作模型视图矩阵 ( lookThrough()
),因此我可以在 3D 空间中“行走”和“旋转”用户视图。walkForward()
它包含允许其他类/对象更改与运动相关的变量(pitch
、、、 )的公共方法(即yaw
)position
。现在,用于用户控件的对象/线程不断更改position
以及yaw
和pitch
. 同时,主窗口(图形)通过使用 - 方法将位置和旋转因子应用于模型视图矩阵lookThrough()
。所有相机移动方法和模型视图矩阵的操作都使用前面提到的一个或所有空间变量。
这是在限制并发线程访问之前提到的相机控制器对象的两个方法。它们清楚地显示了访问相同变量的问题,而相机移动和模型视图矩阵的操作可以同时发生:
// moves camera forward rel. to its current rotation (yaw)
public void walkForward(float distance){
position.x -= distance * (float)Math.sin(Math.toRadians(yaw));
position.z += distance * (float)Math.cos(Math.toRadians(yaw));
position.y += distance * (float)Math.sin(Math.toRadians(pitch));
}
// translate and rotate to look through the camera
public void lookThrough(){
// rotate the pitch around the X-axis
GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f);
// rotate the yaw around the Y-axis
GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f);
// translate to the location defined int he position vector
GL11.glTranslatef(position.x, position.y, position.z);
}
为了限制线程对我假设给定线程的这些变量的访问,Java 的标准Lock
或ReentrantLock
Java 类可以完成这项工作。我可以为每个空间变量创建锁,也可以创建一个来统治它们。假设我要采用多重 ReentrantLock 方法,我无法正确锁定和解锁所有锁定对象。我应该像下面的例子那样做:
lock_pitch.lock();
lock_yaw.lock();
lock_position.lock();
try{
[...]
}
finally{
lock_pitch.unlock();
lock_yaw.unlock();
lock_position.unlock();
}
或者在多个try-finally-blocks中交错锁更可取:
lock_pitch.lock();
try{
lock_yaw.lock();
try{
lock_position.lock();
try{
// put executed code here
}
finally{
lock_position.unlock();
}
}
finally{
lock_yaw.unlock();
}
}
finally{
lock_pitch.unlock();
}
第二个例子对我来说看起来很尴尬。因此,我会选择第一种以较少交错方式锁定和解锁的方法。也许最好只使用一个锁来管理线程访问。这样,锁定和解锁将很简单。在超过一半的情况下,无论如何都会同时访问所有空间变量。也许我可以在使用 - 方法时简单地忽略锁lookThrough()
。用户通过“相机”查看的视图不是线程安全的,但是实际的相机位置是。结果,用户的视图不能被它完全破坏。
足够多的混乱-为简单起见,以下是我总结的主要问题:
- 你会交错锁还是重入锁?在这种特定情况下?
- 当“同时”使用多个锁时,您将如何实际设计代码(我知道这不完全相同)?
- 将信号锁对象汇总到一个锁中以将它们全部锁定是否可取?
- 如果我跟踪在每个渲染循环中应用于该矩阵的实际“相机”位置和旋转,我可以在操作 openGL/LWJGL 中的模型矩阵时简单地忽略使用锁吗?
谢谢你的建议!