Java中的变量值消失
我正在用Java做一个基本的粒子模拟器。现在,我所做的就是让粒子以等效于电力的方式相互作用。这一部分工作得很好(或者至少和您期望的基本模型一样好) 但是,当我添加一些粒子时,程序会丢失它们的位置、速度和加速度值,但不会丢失其他数据(例如,它们的ID号)。对于相同数量的粒子,这并不总是发生。有时,当我添加第四、第五、第二或第三个粒子时,会发生这种情况,但不会添加第一个粒子。它总是发生在我单击添加粒子时,当它失败后,我无法再添加任何东西(这很奇怪),并且粒子不再移动(正如您所期望的,它们的速度和加速度为0) 我将粒子存储在ArrayList中。数组不会丢失数据(我已经检查过了,对象在其中,我甚至可以调用它们的toString()方法并检索它们的ID)。这个问题似乎与同步有关(考虑到它并不总是在同一时刻发生,它似乎有点随机),但我不知道它是什么 我在下面留下所有相关代码Java中的变量值消失,java,variables,physics,Java,Variables,Physics,我正在用Java做一个基本的粒子模拟器。现在,我所做的就是让粒子以等效于电力的方式相互作用。这一部分工作得很好(或者至少和您期望的基本模型一样好) 但是,当我添加一些粒子时,程序会丢失它们的位置、速度和加速度值,但不会丢失其他数据(例如,它们的ID号)。对于相同数量的粒子,这并不总是发生。有时,当我添加第四、第五、第二或第三个粒子时,会发生这种情况,但不会添加第一个粒子。它总是发生在我单击添加粒子时,当它失败后,我无法再添加任何东西(这很奇怪),并且粒子不再移动(正如您所期望的,它们的速度和加速
public class Scene implements KeyListener, MouseListener, MouseMotionListener{
public static ArrayList<Particle> particleArray = new ArrayList<Particle>();
public static Object particleLock = new Object();
public void update() {
synchronized(particleLock) {
for(Particle particle: particleArray) {
double resultX = 0;
double resultY = 0;
for(int i = 0; i<particleArray.size(); i++) {
if(i != particleArray.indexOf(particle)) {
double[] result = PhysicsEngine.applyElectircalForce(particle, particleArray.get(i));
resultX += result[0];
resultY += result[1];
}
}
particle.netForceX = resultX;
particle.netForceY = resultY;
particle.update();
}
}
}
public void mousePressed(MouseEvent e) {
int mouseX = e.getX();
int mouseY = e.getY();
boolean positive = true;
if(e.getButton() == MouseEvent.BUTTON1) {
positive = true;
} else if(e.getButton() == MouseEvent.BUTTON3) {
positive = false;
}
synchronized(particleLock){
particleArray.add(new Particle(mouseX, mouseY, positive));
System.out.println("New particle added at " + mouseX + ", " + mouseY);
}
}
}
public class Particle{
public double x;
public double y;
public Point2D position;
public double velX;
public double velY;
public double acX;
public double acY;
private Color particleColor;
private int radius = 10;
// PHYSICS
public double mass;
public double charge;
public double netForceX;
public double netForceY;
private boolean positive;
public Particle(double x, double y, boolean positive) {
this.x = x - radius;
this.y = y - radius;
this.velX = 3;
this.velY = 2;
this.acX = 0;
this.acY = 0;
this.mass = 100;
this.positive = positive;
if(positive) {
this.charge = defaultCharge;
} else {
this.charge = defaultCharge*(-1);
}
this.position = new Point2D.Double(x, y);
particleColor = Color.WHITE;
}
public void update() {
acX = netForceX / mass;
acY = netForceY / mass;
velX += acX;
velY += acY;
if(x<=0 || x>=Simulation.WIDTH - 23){
velX = velX * -1;
x+= velX;
}
if(y<=0 || y>=Simulation.HEIGHT - 35){
velY = velY * -1;
y+= velY;
}
synchronized(Scene.particleLock) {
for(Particle otherPart: Scene.particleArray) {
if(otherPart.equals(this)) {
continue;
}
double distance = otherPart.position.distance(position);
if(distance <= radius + otherPart.radius) {
//aplicar lo que sé de choques de alguna manera
}
}
}
x+= velX;
y+= velY;
position.setLocation(x, y);
}
}
public class PhysicsEngine {
static double electricalConstant = 100000;
public static double[] applyElectircalForce(Particle thisPart, Particle otherPart) {
double distance = otherPart.position.distance(thisPart.position);
double angle = Math.asin(Math.abs(thisPart.y - otherPart.y)/distance);
double force = (electricalConstant * thisPart.charge * otherPart.charge)/Math.pow(distance, 2);
double forceX = force * Math.cos(angle);
double forceY = force * Math.sin(angle);
if(otherPart.x < thisPart.x) {
forceX = forceX*(-1);
}
if(otherPart.y < thisPart.y) {
forceY = forceY*(-1);
}
double[] result = {forceX, forceY};
return result;
}
}
公共类场景实现KeyListener、MouseListener、MouseMotionListener{
public static ArrayList particleArray=new ArrayList();
公共静态对象particleLock=新对象();
公共无效更新(){
已同步(particleLock){
用于(粒子:粒子光线){
双结果=0;
双结果=0;
对于(int i=0;i我曾经在处理android项目时遇到过类似的同步问题,请尝试声明particleArray volatile,以便编译器知道particleArray将在其他线程或多个线程上更改。如果不起作用,我建议使用队列从不同线程推送对粒子数组的更改然后在update方法中拖动对数组列表的预期更改以更新粒子数组列表。根据我的经验,在不同线程之间直接更改值几乎总是会导致问题。没有任何东西需要同步。为什么要同步particleLock?同步在这里不起作用。您是syncronizing particleLock但您没有使用来自此对象的任何数据。particleLock的目的是什么?@hhafeez显然,他正在同步,这样他就不会在迭代数组的同时添加到数组中,从而消除ConcurrentModificationException的风险。但他没有同步arrya,arrya是实际的rE要同步的资源我看到了它的等价物,但没有必要为锁定义一个新的对象。你应该在不使用任何角度的情况下进行力计算。或者,如果出于某种传统原因必须使用角度,请使用atan2
函数的幂函数来获得单位圆上的正确位置,这也是避免asin
的参数接近1时出现奇点。我看不到代码中有任何线程参与,但如果存在,则肯定应该将数组声明为volatile!我尝试将其声明为volatile,但不起作用。我不确定我是否知道如何执行您所描述的操作。@NicolasMartorell您将哪个变量设置为volatile?