在Java项目上工作,我想知道线程是否已完成所需的计算。
首次尝试:Runnable中的done
变量
头等舱是经理
import uckochfractalfx.UCKochFractalFX;
public class KochManager {
private final UCKochFractalFX application;
private final IEdgeCollection edges;
private int level;
private int count;
public KochManager(UCKochFractalFX application) {
this.application = application;
this.edges = new EdgeArrayList();
}
public synchronized void changeLevel(int nxt) {
this.level = nxt;
this.count = 0;
this.edges.clear();
EdgeGenerator left, right, bottom;
left = new EdgeGenerator(this, EdgeLocation.LEFT);
right = new EdgeGenerator(this, EdgeLocation.RIGHT);
bottom = new EdgeGenerator(this, EdgeLocation.BOTTOM);
Thread tLeft, tRight, tBottom;
tLeft = new Thread(left);
tRight = new Thread(right);
tBottom = new Thread(bottom);
tLeft.start();
tRight.start();
tBottom.start();
while (!(left.isDone() && right.isDone() && bottom.isDone()) {
wait();
}
this.application.setTextCalc(String.valueOf(this.totalTimeExecution));
this.application.setTextNrEdges(String.valueOf(this.count));
application.requestDrawEdges();
}
public synchronized void addEdge(Edge edge) {
this.edges.add(edge);
}
public synchronized void increaseCount() {
count++;
}
public int getLevel() {
return level;
}
public void drawEdges() {
this.application.clearKochPanel();
this.edges.getAll().forEach((Edge e) -> this.application.drawEdge(e));
this.application.setTextDraw(String.valueOf(this.totalTimeExecution));
}
}
这是EdgeGenerator类
import java.util.Observable;
import java.util.Observer;
public class EdgeGenerator implements Runnable, Observer {
private final KochManager kochManager;
private final EdgeLocation edgeLocation;
private final KochFractal koch;
private boolean done;
public EdgeGenerator(KochManager kochManager, EdgeLocation edgeLocation) {
this.kochManager = kochManager;
this.edgeLocation = edgeLocation;
this.koch = new KochFractal();
this.koch.addObserver(this);
}
@Override
public synchronized void run() {
koch.setLevel(kochManager.getLevel());
this.done = false;
switch (this.edgeLocation) {
case LEFT:
this.koch.generateLeftEdge();
break;
case RIGHT:
this.koch.generateRightEdge();
break;
case BOTTOM:
this.koch.generateBottomEdge();
break;
}
this.done = true;
}
public boolean isDone() {
return done;
}
@Override
public void update(Observable o, Object o1) {
this.kochManager.addEdge((Edge) o1);
this.kochManager.increaseCount();
}
}
一切正常,只有一件事,那就是将线程中的对象的值返回到主线程。
我要在此处重点关注的变量是
done
类中的EdgeGenerator
。我在这里尝试了几种方法。
首先是实现,如您在上面的代码中看到的那样:在所有计算之后设置
this.done
,然后应通过调用isDone()
返回该值。但是,当调用
isDone()
时,它总是返回false
第二次尝试:Runnable的调用者中的
done
然后,我决定在
KochManager
中创建一个名为leftDone
的变量,创建一个setter setLeftDone()
并在EdgeGenerator
中对其进行调用。这也总是重调为假。经理:
公共(public)类KochManager {
私有(private)决赛leftDone;
...
public void setLeftDone(boolean done) {
this.leftDone = done;
}
...
public synchronized void changeLevel(int nxt) {
...
while (!(this.leftDone && this.rightDone && this.BottomDone)){
wait();
}
...
}
}
EdgeGenerator:
public class EdgeGenerator {
...
@Override
public synchronized void run() {
...
switch (this.edgeLocation) {
case LEFT:
this.koch.generateLeftEdge();
this.kochManager.setLeftDone(true);
break;
...
}
}
}
正如您可能已经猜想的那样,该方法也不起作用,因此,在进行了更多搜索之后,我决定使用另一个具有单个值的对象。
第三次尝试:创建将保存要设置的变量的
Done
类。经理:
public class KochManager {
private class Done {
public boolean done;
}
...
private Done leftDone;
public KochManager(UCKochFractalFX application) {
this.application = application;
this.edges = new EdgeArrayList();
this.leftDone = new Done();
}
public void setLeftDone(boolean done) {
this.leftDone.done = done;
}
...
public synchronized void changeLevel(int nxt) {
...
while (!(this.leftDone.done && this.rightDone.done && this.BottomDone.done)){
wait();
}
...
}
}
EdgeGenerator:
public class EdgeGenerator {
...
@Override
public synchronized void run() {
...
switch (this.edgeLocation) {
case LEFT:
this.koch.generateLeftEdge();
this.kochManager.setLeftDone(true);
break;
...
}
}
}
一旦解决不了,我决定调用StackOverflow。
有人可以帮我吗?
最佳答案
您需要使用Option-1,但是将done
变量标记为volatile
,如下所示,,否则其他线程将不能保证看到done
变量的更改。
private volatile boolean done;
以下是来自here的有关
volatile
的引用