你可以从它的外观创造世界final
。那么这将向您展示同步访问的徒劳:
public class PhysicsProcessor extends Runnable {
private final DynamicsWorld world;
public synchronized DynamicsWorld getDynamicsWorld() { return world; } //why sync? it can't change
}
您会看到,当您这样做时:同步在返回myPhysicsProcessor.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);
}
}
然后你会这样做,添加一个身体:
myPhysicsProcessor.do(new IWorldRunable(){
@Override
public void run(DynamicsWorld world){
world.addRigidBody(...);
}
});
它会在下stepSimulation
一个线程之前执行,所以不用担心线程。