スレッドを使用してJavaプログラムを作成していますが、いくつかの問題が発生し続けています。Javaスレッドが中断していない
学校向けのプロジェクトであり、コッホのフラクタルをいくつか作成する必要があります。
最初のクラスはマネージャです。 EdgeGeneratorを使用してKochフラクタルのエッジを生成するスレッドが作成されます。
import java.util.logging.Level;
import java.util.logging.Logger;
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();
try {
tLeft.join(500);
tRight.join(500);
tBottom.join(500);
} catch (InterruptedException ex) {
Logger.getLogger(KochManager.class.getName()).log(Level.SEVERE, null, ex);
}
application.requestDrawEdges();
}
public void addEdge(Edge edge){
this.edges.add(edge);
}
public synchronized void increaseCount(){
count ++;
}
public int getLevel() {
return level;
}
}
2番目のクラスは、RunnableとObserverを実装するEdgeGeneratorです。
観測可能なのはKochFractalクラス(ここには含まれていません)です。 updateメソッドは、KochFractalのgenerate__Edge()メソッドで呼び出されます。 これはすべて正常に動作し、スレッドとスレッドを使用せずにテストされます。
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;
public EdgeGenerator(KochManager kochManager, EdgeLocation edgeLocation) {
this.kochManager = kochManager;
this.edgeLocation = edgeLocation;
this.koch = new KochFractal();
this.koch.addObserver(this);
}
@Override
public void run() {
koch.setLevel(kochManager.getLevel());
switch (this.edgeLocation) {
case LEFT:
this.koch.generateLeftEdge();
break;
case RIGHT:
this.koch.generateRightEdge();
break;
case BOTTOM:
this.koch.generateBottomEdge();
break;
}
Thread.currentThread().interrupt();
}
@Override
public void update(Observable o, Object o1) {
this.kochManager.addEdge((Edge)o1);
this.kochManager.increaseCount();
}
}
最後のクラスは、ArrayListを使用するコレクションクラスです。 追加と削除時にsynchronizedキーワードを使用しました。これにより、インスタンスメソッドは一度に1つのスレッドのみにアクセス可能になり、他のスレッドを保留にすることができます。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class EdgeArrayList implements IEdgeCollection{
private final List<Edge> edges;
public EdgeArrayList() {
this.edges = new ArrayList<>();
}
@Override
public synchronized void add(Edge e) {
edges.add(e);
}
@Override
public synchronized void remove(Edge e) {
edges.remove(e);
}
@Override
public void clear() {
edges.clear();
}
@Override
public List<Edge> getAll() {
return Collections.unmodifiableList(edges);
}
}
ここでは何が起こっていますか?
- ここに実装されているようにプログラムを実行すると、フラクタル要素のうちのほんの一部がGUIに表示されます。 しかし、いったん多くの辺を計算しなければならない場合、それらの辺はguiに表示されます。 デバッガを使用すると、すべてのエッジが計算されていることがわかりますが、すべてのエッジが計算される前に
application.requestDrawEdges();
が呼び出されました。 join()
メソッドで遅延なしでプログラムを実行すると、GUIは表示されずに実行されます。
は、私の知る限りではThread.currentThread().interrupt();
は、現在のスレッドを停止し、join()
メソッドを呼び出し、それは起きていないはずです。
誰かが私を正しい方向に向けることを願っています。
@GhostCat私の悪い、私はちょうどそれを夜に呼び出す前に、この質問を投稿しました。私はすぐにこれに取り組み始め、あなたに知らせます。 –
受け入れてくれてありがとう、私は助けになってうれしいです。 – GhostCat