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

时间:2014-08-17 14:15:14

标签: java vector

我正在编写一个应用程序来计算二次方程的delta和根,接受其系数作为输入。后来,我想给它一个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;如果是s 2 2 -12 delta仍然是25岁,但它显示2)。 不知何故,这个载体的第一个元素没有被删除和替换,但我不知道为什么;我只知道它不是同步问题,因为我试图删除所有的同步,输出是相同的。

那么,我的错误是什么?谢谢。

2 个答案:

答案 0 :(得分:0)

所有多线程内容的重点是什么?

synchronized (data) {

这会同步您以后永远不会使用的对象

launch.start();
if (data.size()!=0) {

在使用数据之前,您甚至不等待线程完成,尝试添加join

launch.start();
launch.join();
if (data.size()!=0) {

我建议你首先构建一个没有线程化工作的应用程序,然后从那一点开始添加多线程。

我认为让同一个对象保持输入和输出

是一种不好的做法

您在构造函数中传递的向量与您期望得到的向量相同。我认为,在Calculate内,你应该有另一个向量来保存结果,当线程完成后,访问结果如:

launch.getResult()

一些代码改进

Vector data=new Vector ();
//...
data = v;

从不使用在第一行创建的向量。 data = v不会将v中的每个值复制到数据中。您可以使用:

data.addAll(v);

while (z.size()!=0) {
    z.removeElementAt(0);
}

最好做z.clear();

答案 1 :(得分: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));
}

当你执行launch.start()时,计算开始但在其他线程中,并且此线程仍在运行,因此它开始打印数据Vector的元素。这些元素尚未更新。

尝试在Thread.sleep(2000);之前添加if (data.size()!=0),看看结果是否会改变为您期望的结果。这样,在另一个打印输出之前,您将使一个线程完成它的工作。 这当然不是解决方案 - 它只会显示问题所在。如果你想要一个解决方案,请查看java.util.concurrent,你可以找到像CoundDownLatch这样有用的东西。

此外,您经常使用synchronized关键字,而且并非必要。您应该始终小心使用synchronized。 试试这本书:

http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601

但请记住,Java中的并发性是非常先进的主题。