我的问题是,对于特定情况,是否是交错多个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);
}
为了限制线程对这些变量的线程访问,我假设,标准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()
- 方法时忽略锁定。通过“相机”的用户视图不是线程安全的,但实际的相机位置是。因此,用户的视图不会被它完全破坏。
足够的大规模混淆 - 以下是我为简单起见总结的主要问题:
感谢您的建议!