分离线程但仍保留java中的公共变量

时间:2016-05-11 09:12:55

标签: java multithreading updates

我的项目组正在创建流量模拟,我们不确定如何正确地拆分线程。我们有下面的更新方法,它有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;
}

2 个答案:

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