我的项目组正在创建流量模拟,我们不确定如何正确地拆分线程。我们有下面的更新方法,它有1个变量delta。现在我们想要分割两个循环(在第一个和第二个更新车辆更新所有交叉点等)。如何将这些分为2个线程,但仍然可以为delta提供相同的值?这甚至可能吗?我们只能将整个方法放入1个线程中,但是我们不能拆分它们。
编辑:delta是一个不断变化的变量(时间过去)这就是很难同时使用相同delta的原因。
public void update(double delta){
for (int i = 0; i < this.vehicles.size(); i++) {
this.vehicles.get(i).update(delta);
}
for (int i = 0; i < this.updateables.size(); i++) {
this.updateables.get(i).update(delta);
}
this.simulationTime += delta;
}
答案 0 :(得分:0)
如果我理解你,delta可能会有所不同。
你可以创建两个单独的线程,例如这里的车辆:
public class VehiclesUpdater extends Thread {
double delta;
List<Vehicle> vehicles;
public VehiclesUpdater(double delta, List<Vehicle> vehicles) {
this.delta = delta;
this.vehicles = vehicles;
}
@Override
public void run() {
for(int i=0;i<vehicles.size();i++) {
vehicles.get(i).update(delta);
}
}
}
然后,不要调用循环,只需执行以下操作:
public void update(double delta) {
Thread t = new VehiclesUpdater(delta, vehicles);
t.start();
//the same here for the Updateables
}
编辑: 因为您涉及时间问题,您可以尝试使用Observer / Observable方法。
让您的Vehicle-class和您的Updateable类扩展Observer类:Observer
在计算delta-value(s)的类中,实现Observable接口。如果它发生变化,请调用setChanged()
方法,然后调用notifyObservers()
方法,并将delta或Double-Wrapper作为参数给出:
Double wrapper = new Double(delta);
setChanged();
notifyObservers(wrapper);
在您的汽车级别中,您必须覆盖观察者的update-method
:
//
@Override
public void update(Observable o, Object arg) {
this.updateDelta((Double)arg);
}
我刚刚调用了你的原始更新方法updateDelta来澄清 - 只要你的update-method将使用另一个param(double)并且具有相同的方法头与public void update,它应该可以在这里使用方法重载(...)。
答案 1 :(得分:0)
如果this.vehicles
是一个列表,或者沿着这些行的某些内容,则创建一个并行流。
this.vehicles.stream().parallel().forEach(v->v.update(delta));
然后他们应该并行运行。
另一种方法是,如果您想要更好地控制流程,请使用执行程序服务。
ExecutorService service = Executors.newFixedThreadPool(4);
然后提交每项任务。
List<Future<?>> futures = this.vehicles.map(
v->service.submit(
()->v.update(delta)
)
).collect(Collectors.toList());
然后确保完成所有任务。
futures.forEach(future->{
try{
future.get();
}catch(Exception e){
//two types of exceptions they both should be handled appropriately.
}
});