Java JBullet NullPointer在独立线程中的阶跃模拟
我在我的游戏中有一个设置,物理在一个单独的线程中更新,实现如下 物理处理器(物理线程) 在主线程中创建对象的示例Java JBullet NullPointer在独立线程中的阶跃模拟,java,multithreading,nullpointerexception,bulletphysics,jbullet,Java,Multithreading,Nullpointerexception,Bulletphysics,Jbullet,我在我的游戏中有一个设置,物理在一个单独的线程中更新,实现如下 物理处理器(物理线程) 在主线程中创建对象的示例 myPhysicsProcessor.getDynamicsWorld.addRigidBody(/* some rigid body created here */); 问题是,当游戏运行时,我偶尔会在“stepSimulation”的单独线程中得到一个空指针异常,这是由dbvt broadphase中的setAabb引起的 有人对我能做些什么来防止这个异常,或者如何解决它有什么
myPhysicsProcessor.getDynamicsWorld.addRigidBody(/* some rigid body created here */);
问题是,当游戏运行时,我偶尔会在“stepSimulation”的单独线程中得到一个空指针异常,这是由dbvt broadphase中的setAabb引起的
有人对我能做些什么来防止这个异常,或者如何解决它有什么建议吗?从外观上看,你可以让世界成为最终的。那么,这将表明同步访问是徒劳的:
public class PhysicsProcessor extends Runnable {
private final DynamicsWorld world;
public synchronized DynamicsWorld getDynamicsWorld() { return world; } //why sync? it can't change
}
你看,当你这样做:myphysicprocessor.getDynamicsWorld().addRigidBody(…)
同步在getDynamicsWorld()返回后停止。因此在安全同步上下文之外调用addRigidBody(…)
否,您要做的是确保它始终在同步块中使用:
@Override
public void run() {
//update physics
synchronized(this) {
world.stepSimulation(/* delta time */);
}
}
public void addBody(/*args here*/) {
synchronized(this) {
world.addRigidBody(/*args here*/);
}
}
现在,对于一种方法来说,这是可以的,但是如果您发现自己希望以这种方式在运行程序之外执行许多DynamicsWorld
方法,或者只需要另一种选择,那么此方法不需要同步:
public interface IWorldRunable {
void run(DynamicsWorld world);
}
public class PhysicsProcessor extends Runnable {
private final DynamicsWorld world;
private final ConcurrentLinkedQueue<IWorldRunable> worldRunables = ConcurrentLinkedQueue<IWorldRunable>();
public PhysicsProcessor() {
/* basic dynamics world setup with dvbt broadphase :P */
}
@Override
public void run() {
/* update time */
//run runables on world
for(IWorldRunable runable : worldRunables)
runable.run(world);
//clear runables
worldRunables.clear();
//update phyics
world.stepSimulation(/* delta time */);
}
public void do(IWorldRunable runnable) {
worldRunables.add(runnable);
}
}
它将在下一个stepSimulation
之前在同一个线程上执行,因此线程不必担心。何时创建world
?它将由PhysicProcessor的构造函数创建,该构造函数将在我的主线程中的某个位置调用,这可能是导致空值的原因。您在这里介绍的代码很好。您能发布构造函数的代码吗?代码有点不同,因为在动态世界中:broadphaseInterface=new DbvtBroadphase();collisionConfiguration=新的DefaultCollisionConfiguration();collisionDispatcher=新的collisionDispatcher(collisionConfiguration);constraintSolver=新的顺序脉冲constraintSolver();dynamicsWorld=新的离散dynamicsWorld(碰撞调度器、宽相位接口、约束解决方案、碰撞配置);我可以告诉你,我知道世界不是空的
public interface IWorldRunable {
void run(DynamicsWorld world);
}
public class PhysicsProcessor extends Runnable {
private final DynamicsWorld world;
private final ConcurrentLinkedQueue<IWorldRunable> worldRunables = ConcurrentLinkedQueue<IWorldRunable>();
public PhysicsProcessor() {
/* basic dynamics world setup with dvbt broadphase :P */
}
@Override
public void run() {
/* update time */
//run runables on world
for(IWorldRunable runable : worldRunables)
runable.run(world);
//clear runables
worldRunables.clear();
//update phyics
world.stepSimulation(/* delta time */);
}
public void do(IWorldRunable runnable) {
worldRunables.add(runnable);
}
}
myPhysicsProcessor.do(new IWorldRunable(){
@Override
public void run(DynamicsWorld world){
world.addRigidBody(...);
}
});