【问题标题】:Wait for method within loop to complete before looping again在再次循环之前等待循环内的方法完成
【发布时间】:2020-01-04 17:28:15
【问题描述】:

我正在构建一个 java fx 应用程序并在其自己的线程上有一个 while 循环,但该循环不等待 Dijkstra 方法返回一个数组,我似乎通过将线程休眠 1000 毫秒和我真的不知道为什么会这样,但有没有更好的方法让我可以等待方法完成然后开始下一次迭代?

    public class Chasers {

    public volatile List<List<Integer>>  Path; ///////

   volatile int ChaserX;
   volatile int ChaserY;
   volatile int PlayerX;
   volatile int PlayerY;

   boolean Continue=true;


volatile int  PathSize = 0;
int dir = 5;
volatile int i=0;
Main MainPassed=new Main();
DijkstraSolve PathFinder = new DijkstraSolve();

  Task<Void> task = new Task<Void>() {

        @Override protected Void call() throws Exception {

            while (Continue) {
                i = 0;
                width = MainPassed.width;
                ChaserX = ((int) (PlayerIns.chaser.getCenterX() / width) * width);
                ChaserY = ((int) (PlayerIns.chaser.getCenterY() / width) * width);
                PlayerX = ((int) (PlayerIns.player.getCenterX() / width) * width);
                PlayerY = ((int) (PlayerIns.player.getCenterY() / width) * width);
                Path = PathFinder.Dijkstra(ChaserX, ChaserY, PlayerX, PlayerY, MainPassed);//wait for this to return??
                PathSize = Path.size() - 1;

            }

            return null;
        }
    };
    Thread th = new Thread(task);
    //th.setDaemon(true);
    th.start();



     public void MoveChaser(Player PlayerIns){
    Timeline timeline = new Timeline(new KeyFrame(Duration.millis(50), new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println(" current path "+Path);
            System.out.println("==============================");



        }
    }));
    timeline.setCycleCount(Timeline.INDEFINITE);

    timeline.play();
}

}

【问题讨论】:

  • Dijkstra() 是否也在新线程中运行?如果没有,循环会等待它完成。为什么你认为没有?
  • 只是在调用它的同一个线程中运行,它只是不断地调用它,尽管它没有完成。
  • 永远是真的只是希望它一直在寻找最新的路径。没有说清楚
  • 我在下面的评论中看到您正在使用 UI。这可能是问题所在,需要一些时间来更新。循环确实等待Dijkstra()完成。
  • 请提供一个minimal reproducible example 来说明问题。与您的问题无关:请学习 java 命名约定并遵守它们。也就是说:您不得从 fx 应用程序线程修改场景图。

标签: java multithreading loops recursion javafx


【解决方案1】:

您正忙于循环并可能使 UI 线程处于饥饿状态。 您还没有展示如何声明变量。 (而且您使用的是非标准命名约定,这会造成混淆。请不要用大写字母命名变量,以免它们看起来像类。)

也许 Path 变量(应该命名为 'path')没有声明为 volatile?

【讨论】:

  • 是的,我将“路径”字段设置为 volatile 但没有运气:(
  • 您能否编辑问题以说明实际发生的情况与您想要发生的情况?我们已经确定循环正在(必须)等待 Dijkstra 方法返回。变量等的类型是什么?什么是“路径”?
  • 路径只是一个二维坐标数组。然后我想从时间线访问它,但它总是空的,但是当从线程中打印 Path 时,它不是空的并且是正确的。
  • 这就像线程“路径”之外没有看到修改
  • 您是否在 Timeline 事件中看到 Path 正在被新的数组实例替换?
【解决方案2】:

您可以通过使用join() 方法来实现这一点,当从父线程调用此方法时,父线程会等待子线程终止。在th.start() 之后使用th.join()。您的任务应该在这两个命令的执行之间运行。

阅读multithreading basicsJava doc

【讨论】:

  • 谢谢,试一试,ui卡住了?,我会继续摆弄它
  • 它冻结了,因为 Continue 总是 true ,所以我认为子线程永远不会终止
  • 由于 JavaFX 应用程序线程的性质,即使线程在有限时间内完成,也不能使用join。应用程序线程不得长时间(几毫秒)阻塞,以避免 ui 冻结。链接的教程也不包含任何有助于在这种情况下提供帮助的其他信息(即使有,我们也需要将其视为仅链接的答案)。
  • “摆弄”是多线程的灾难之路。发展理解和清晰的概念是唯一的选择。如果可能,您还应该避免使用低级线程功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 2021-12-26
  • 2021-12-27
  • 1970-01-01
  • 2014-07-19
  • 2018-02-08
相关资源
最近更新 更多