Java:在两个类之间共享向量
我正在写一个应用程序,计算二次方程的增量和根,接受它的系数作为输入。稍后,我想给它一个GUI 这是一个计算所有内容的类: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
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));
}