有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java需要帮助在自制的仓鼠模拟器上实现启动/恢复/暂停/停止线程操作

项目:

Completely recreate the known Hamster Simulator using Java, currently working on buttons to start/pause/resume/stop the simulation, which is running as a Thread. Screenshot of current progress

问题:

As the user can input loops into the editor, my usual method of using while(!stopped) does not work because this loop only ends after the loop the user has input has ended. See walkInCircles() from the picture above for explanation, with this kind of input the hardcoded while(!stopped) would never be left.

MCVE代码

public class RunnableGame extends Thread {

private final Object lock = new Object();
private volatile boolean suspend = false, stopped = false; 

  @Override
    public void run() {
     while (!stopped){        //This loop will not be left if the user inputs any loops
        while (!suspend){    //This loop will not be left if the user inputs any loops
                /* Stripped down for readability
                method.invoke();
                updateObserver();
                */
        }
        synchronized (lock){
            try {
                lock.wait();
            } catch (InterruptedException ie){
                Thread.currentThread().interrupt();
                return;
            }
        }
    }
}

  public void suspendThread(){
    suspend = true;
}

  public void stopThread(){
    suspend = true;
    stopped = true;
    synchronized (lock) {
        lock.notifyAll();
    }
}

  public void resumeThread(){
    suspend = false;
    synchronized (lock) {
        lock.notifyAll();
    }
}

我需要什么

A different way to start/pause/resume/stop a Thread in Java.

非常感谢您的转发<;三,


共 (2) 个答案

  1. # 1 楼答案

    如果不指定无限循环的缺乏,我觉得这个问题本质上是不可能的。如果提供的方法的持续时间是无限的,并且您的类从未从该方法获得过优先级,那么在它终止之前,您无法与它进行交互

    基本上,interrupted状态是Thread子类和Runnables必须遵循的约定:如果所处的线程中断,则必须停止正在执行的操作,要么处理它,要么完全终止线程。通过允许用户输入一个自定义方法(可能包含一个无限循环),您允许创建不尊重其运行线程中断状态的方法,这意味着interrupt()调用的任何配置都不会起作用

    所有这一切都有点让人想起停止问题,因为您正试图与一个子例程进行交互,该子例程可能永远持续,而不会告诉外部例程任何新信息。我不确定它是否真的可以解决

    最简单的替代方法是(非正式地)要求用户输入的方法只对应于他们想要运行的任何循环的单个步骤。然后在两个步骤之间,您可以自己执行中断状态检查,我认为您当前的代码可以实现这一点

  2. # 2 楼答案

    没有要求(至少从我读到的)外部例程不修改内部例程(用户代码)。由于我不确定您是如何执行此用户代码的,所以我只能对您如何解决此问题含糊其辞

    假设您有权执行给定的代码,那么您可以简单地解析代码并删除挂起/停止检查条件,作为循环继续执行的要求的一部分

    这可以通过多种方式实现,最简单的方法是通过直接符号替换。过滤出字符串等的段,类似于:

    replace("while(", "while(!suspend && !stop &&");
    

    将实现这一技巧(考虑可能的空格/换行符以及其间的各种组合)

    这种技术也应该扩展到for循环

    此外,您应该中断线程以取消用户代码抛出的任何潜在长时间运行的任务(例如Thread.sleep())。并吸收来自用户代码的异常

    鉴于您似乎能够直接解析用户代码,在自己的代码体中编译并执行,这里描述的技术在您的程序中应该是可行的。您可以做的最好的事情是限制用户可以键入的内容,或者对用户代码进行不可见的修改,而不会对所述代码的执行产生不利影响

    是否可能包含用户可能键入的所有内容,并使其仍能正常工作,这是一个我不知道答案的问题。尽管如此,从用户代码中对System.exit(0)的简单调用似乎可以做到这一点:)