如何在杀死原始线程的同时递归地启动多个线程



我不知道如何转换我编写的函数,使其在Java中同时作为多个线程运行。

该函数取一个根,该根对于每个线程都是不同的;"分割";在给定的连接点(用于此操作的if语句在函数中,每个新创建的线程将来也应该能够在下一个连接点分离(。

我希望所有线程一旦到达目标就会死亡;而";用于检查它们是否已到达终点的循环也在函数中。

基本上,我希望函数能够同时运行多次,每次都有一个修改的起点;原始的";线在分裂之前要被杀死。

我也不能扩展Thread,因为我已经在扩展另一个类了,所以我试图通过实现Runnable来实现它。

这是课程(父课程运行良好,所以我认为我不需要发布它们(:

public class Multithreaded extends ParentClass implements Runnable {
@Override
public void run() {
executeThread(modelThreaded, new HashMap<>());
}
private final Set<Tile> VISITED = new HashSet<>();
private Grid modelThreaded; //to be able to update the root?
public Multithreaded() {
super();
}
@Override
protected int runPathfinder(Grid model, List<Tile> path) {
HashMap<Tile, Integer> tileData = new HashMap<>();
this.modelThreaded = model;
this.executeThread(model, tileData);
int cost = tileData.get(model.getTarget()) - 1;
this.statistics.setPathFound(true, cost);
this.painter.drawPath(path, model);
return cost;
}
private void executeThread(Grid model, HashMap<Tile, Integer> tileData) {
// Keeps track of visited tiles
VISITED.add(model.getRoot());
//start at the root
Tile currentTile = model.getRoot();
List<Tile> posNeighbors = model.getTileNeighbors(currentTile);
List<Tile> validNeighbors = new ArrayList<>();
int DEFAULT_DISTANCE = 1;
tileData.put(model.getRoot(), DEFAULT_DISTANCE);
int iteration = 0;
while (!isVisited(model.getTarget())) {
iteration++;
posNeighbors.clear();
validNeighbors.clear();
posNeighbors = model.getTileNeighbors(currentTile);
validNeighbors = getForward(posNeighbors);
//debugging
System.out.println("Valid Neighbors for currentTile ("
+ currentTile.getX() + ", " + currentTile.getY() + "): ");
for (Tile validNeighbor : validNeighbors) {
System.out.println(validNeighbor.getX() + ", " + validNeighbor.getY());
}
// tries to split along junctions into multithreads
// tries to kill mouse if there's a dead end
if (validNeighbors.size() > 0) {
for (Tile validNeighbor : validNeighbors) {
currentTile = validNeighbor;
// want to create a new thread for each validNeighbor here, but with
// a small change: the root changes to the current validNeighbor
model.setRoot(validNeighbor);
Runnable runnable = new Multithreaded();
Thread thread = new Thread(runnable);
thread.start();
}
}
//attempt to kill/stop current thread if there are no more options left for that thread
else {
break;
}

VISITED.add(currentTile);
tileData.put(currentTile, DEFAULT_DISTANCE + iteration);
}

private List<Tile> getForward(List<Tile> posNeighbors) {
List<Tile> validNeighbors = new ArrayList<>();
for (Tile posNeighbor : posNeighbors) {
if (posNeighbor != null && !posNeighbor.isWall()
&& !isVisited(posNeighbor)) {
validNeighbors.add(posNeighbor);
}
}
return validNeighbors;
}
private boolean isVisited(Tile posNeighbor) {
for (Tile visitedTile : VISITED) {
if (visitedTile == posNeighbor) {
return true;
}
}
return false;
}
}

正如你所看到的,我希望线程继续运行,除非:

  1. 其中一个遇到目标(model.getTarget(((或
  2. 它达到了存在0个有效邻居的点

当一个线程有1个有效邻居时,它应该保持奇异并沿着该路径前进,直到它到达另一个结点或死胡同(getForward只返回未访问的邻居(

因此,当一个线程遇到一个结点(2个validNeighbors(时,它应该一分为二,杀死原始线程(停止执行executeThread,这就是我在其中插入中断的原因(,每个方向有一个线程,然后继续运行算法。使用我当前的代码,它可以正确地沿着路径运行,但不会分裂成不同的线程,当遇到死胡同时也不会停止运行。

让它运行的最佳方式是什么?我把executeThread((放在run((中是正确的,还是应该放在其他地方?我试过只做runnable.run((,而不是Threadthread和Thread.start((,但这似乎没有帮助。我真的不知道在这里该怎么办,我觉得我错过了一些显而易见的东西。。。

EDIT:runPathfinder是父类调用的函数,以便所有这些代码运行

我认为下面的mre(1(再现了所需的多线程功能

每个节点(状态/瓦片(都由一个整数表示
getTileNeighbors返回3个随机邻居
所有线程共享一个同步的visited集合,并且应该在target添加到visited之后停止
(将整个代码复制粘贴到Main.java并运行(

import java.util.*;
public class Main   {
public static void main(String[] args) {
new Thread(new Multithreaded(0, 20)).start();
}
}
class Multithreaded  implements Runnable {
// Synchronized Set (shared between threads)
private static final Set<Integer> visited = Collections.synchronizedSet(new HashSet<Integer>());
private final int root, target;
//root and target assumed >=0
public Multithreaded(int root, int target) {
this.root = root;
this.target = target;
}
@Override
public void run() {
executeThread(root);
}
private void executeThread(int root) {
visited.add(root);
System.out.println("New thread, root="+ root);
while (!isStopConditionMet()) {
List<Integer> neighbors = getTileNeighbors(root);
//todo if  neighbors is empty break out of the while loop

for (Integer neighbor : neighbors) {
if(! visited.add(neighbor)) {
continue; //skip is already visited
}
Runnable runnable = new Multithreaded(neighbor, target);
Thread thread = new Thread(runnable);
thread.start();
}
}
}
//returns a list o 3 random numbers between 0-target (inclusive)
//to represent 3 random neighbors
private List<Integer> getTileNeighbors(int currentTile) {
Random rnd = new Random();
int maxValue = target +1;
return Arrays.asList(rnd.nextInt(maxValue), rnd.nextInt(maxValue), rnd.nextInt(maxValue));
}
private boolean isStopConditionMet() {
return visited.contains(target);
}
}

(1(mre应该证明要解决的问题,而不是具体的应用

最新更新