Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JBullet NullPointer在独立线程中的阶跃模拟_Java_Multithreading_Nullpointerexception_Bulletphysics_Jbullet - Fatal编程技术网

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(...);
  }
});