Java:在两个类之间共享向量

Java:在两个类之间共享向量,java,vector,Java,Vector,我正在写一个应用程序,计算二次方程的增量和根,接受它的系数作为输入。稍后,我想给它一个GUI 这是一个计算所有内容的类: package functions; import java.util.*; public class Calculate implements Runnable { double a=0; double b=0; double c=0; double delta = 0; double r1=0; double r2=0; Vector data=new Vector

我正在写一个应用程序,计算二次方程的增量和根,接受它的系数作为输入。稍后,我想给它一个GUI

这是一个计算所有内容的类:

package functions;

import java.util.*;

public class Calculate implements Runnable {
double a=0;
double b=0;
double c=0;
double delta = 0;
double r1=0;
double r2=0;
Vector data=new Vector ();

public Calculate (Vector v) {
    synchronized (data) {
        synchronized (v) {
            data = v;
        }
        a =(double) data.elementAt(0);
        b =(double) data.elementAt(1);
        c =(double) data.elementAt(2);
    }
}
public double calcDelta () {
    delta = b*b-4*a*c;
    return delta;
}
public double root1 () {
    r1 = (-b+Math.sqrt(delta))/(2*a);
    return r1;
}
public double root2 () {
    r2 = (-b-Math.sqrt(delta))/(2*a);
    return r2;
}
public void createData (Vector z) {
    synchronized (z) {
        while (z.size()!=0) {
            z.removeElementAt(0);
        }
        z.add(delta);
        z.add(r1);
        z.add(r2);
    }

}
public void run () {
    calcDelta();
    root1 ();
    root2 ();
    //try {
        createData (data);
    //} catch (InterruptedException e) {}
}
}
我已经测试过了,效果很好。问题出在我为它编写的测试代码中:

import java.util.*;

import functions.*;

public class Test {
double a=0;
double b=0;
double c=0;
Vector v = new Vector ();
public Test (double arturo, double bartolomeo, double cirinci) {
    a=arturo;
    b=bartolomeo;
    c=cirinci;
    synchronized (v) {
        v.add(a);
        v.add(b);
        v.add(c);
    }
}
public Vector makevector () {
    return v;
}
public static void main (String [] args) {
    double art = (double) Integer.parseInt (args[0]);
    double bar = (double) Integer.parseInt (args[1]);
    double car = (double) Integer.parseInt (args[2]);

    Test t = new Test (art, bar, car);

    Thread launch;
    Vector data = t.makevector();
    Calculate res = new Calculate (data);
    launch = new Thread (res);

    launch.start();

    if (data.size()!=0) {
        System.out.println ("Delta: "+data.elementAt(0));
        System.out.println ("Radice 1: "+data.elementAt(1));
        System.out.println ("Radice 2: "+data.elementAt(2));
    }
}
}
特别是在Delta的输出中。事实上,根的显示是正确的,但它不是delta,而是打印a系数(举例来说,如果我通过1 1-6,我希望delta是25,但它显示1;如果是2 2-12,delta应该仍然是25,但它显示2)。 不知何故,这个向量的第一个元素没有被删除和替换,但我不知道为什么;我只知道这不是一个同步的问题,因为我试图删除所有的同步和输出是相同的

那么,我错在哪里?谢谢。

所有多线程的东西有什么意义? 这将同步一个以后永远不会使用的对象

launch.start();
if (data.size()!=0) {
在使用数据之前,您甚至不必等待线程完成,请尝试添加
join

launch.start();
launch.join();
if (data.size()!=0) {
我建议您首先构建一个不使用线程的应用程序,然后从这一点开始添加多线程

我认为让同一个对象保存输入和输出是一种不好的做法 在构造函数中传递的向量与期望结果的向量相同。我认为,在
Calculate
中,应该有另一个向量来保存结果,当线程完成时,访问结果,如下所示:

launch.getResult()
一些代码改进 在第一行上创建的向量永远不会使用
data=v
不会将v中的每个值复制到数据中。您可以使用:

data.addAll(v);

最好做
z.clear()

您的问题(可能)是在打印之前计算尚未完成

请看一下代码的这一部分:

launch.start();

if (data.size()!=0) {
    System.out.println ("Delta: "+data.elementAt(0));
    System.out.println ("Radice 1: "+data.elementAt(1));
    System.out.println ("Radice 2: "+data.elementAt(2));
}
当您启动.start()时,计算开始,但在另一个线程中,该线程仍在运行,因此它开始打印数据向量的元素。这些元素还没有更新

尝试添加
Thread.sleep(2000)if(data.size()!=0)
之前输入code>,然后查看结果是否更改为您期望的结果。这样,您将使一个线程在另一个线程打印输出之前完成它的工作。 这当然不是解决办法——它只会说明问题所在。如果您想要一个解决方案,请查看java.util.concurrent,在那里您可以找到一些有用的东西,如ConditDownLatch

此外,您经常使用
synchronized
关键字,但并不一定正确。使用
synchronized
时应始终小心。 试试这本书:


但请记住,Java中的并发性是一门相当高级的学科。

您似乎从1999年开始学习Java。从那时起,Java有了很大的发展。向量不应该再使用了。收藏是通用的。使用
ArrayList
。或者更好的是,定义一个SecondDegreeEquation类,包含3个double类型的字段:a、b和c。使其不可变。不要将计算结果存储在包含其输入的结构中。不要期望你一开始就得到答案。线程并行执行。坦白地说,在处理线程之前,你应该先学习Java和OO的基础,这是一个复杂的问题;这段代码类似于我在那里找到的一个示例;看起来,在那个时候讨论线程不仅是老生常谈,而且是非常错误的……这是我书中的一个例子,展示了线程是如何工作的。现在我知道它们怎么不起作用了,呵呵。不……现在更让人困惑了。在添加join()或sleep(2000)之后,现在它返回系数而不是结果;计算类仍然有效。哦,好吧,我想在尝试你的指南之前,我会尝试阅读更多的基本(和最新的)指南,即使这个问题得到解决。无论如何谢谢你。@daniele squalo我用
Thread.sleep(2000)试过你的代码
launch.join(),两者都有效。当我输入[1,1,-6]时,我得到了[25,2,-3],肯定有一些不想要的行我忘记删除了,或者在删除一些错误时,我破坏了一些好的东西;从本主题返回代码并添加join()后,看起来您是对的。多亏了你,我才腾出了一些时间,现在我可以学到更多。
data.addAll(v);
while (z.size()!=0) {
    z.removeElementAt(0);
}
launch.start();

if (data.size()!=0) {
    System.out.println ("Delta: "+data.elementAt(0));
    System.out.println ("Radice 1: "+data.elementAt(1));
    System.out.println ("Radice 2: "+data.elementAt(2));
}