分离线程但仍然在 java 中保留一个公共变量

separating threads but still keeping a common variable in java

我的项目组正在创建流量模拟,我们不确定如何正确拆分线程。我们有下面的更新方法,它有 1 个变量增量。现在我们想拆分两个 for 循环(在第一个和第二个更新车辆更新所有交叉路口等)。如何将它们分成 2 个线程,但仍然能够为它们提供相同的增量值?这可能吗?我们只能将整个方法放入 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;
}

如果我没理解错的话,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-approach.

让你的 Vehicle-class 和你的 Updateable-class 扩展 Observer class: Observer

在计算增量值的 class 中,实现 Observable 接口。如果它发生变化,调用 setChanged() 方法,然后调用 notifyObservers() 方法,并给它 delta 或 Double-Wrapper 作为参数:

Double wrapper = new Double(delta);
setChanged();
notifyObservers(wrapper);

在你的载具中-class,你必须覆盖 Observer 的 update-method

//
@Override
public void update(Observable o, Object arg) {
    this.updateDelta((Double)arg);
}

我刚刚调用了您的原始更新方法 updateDelta 进行说明 - 只要您的更新方法将使用另一个参数 (double) 并且具有与 public无效更新(...)。

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