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