线程只能在Java中执行某些方法吗?

线程只能在Java中执行某些方法吗?,java,multithreading,Java,Multithreading,我正在为机器人制作一个界面。我的机器人类有一些方法,包括移动、停止移动和读取传感器数据。如果可能的话,我希望在给定的线程下运行某些方法,在另一个线程下运行某些其他方法。我希望能够向robot对象发送移动命令,让执行该命令的线程睡眠持续毫秒,然后停止移动,但我希望能够调用stop方法并中断执行移动的线程。非常感谢您的帮助 public class robotTest { public static void main(String[] args) throws InterruptedEx

我正在为机器人制作一个界面。我的机器人类有一些方法,包括移动、停止移动和读取传感器数据。如果可能的话,我希望在给定的线程下运行某些方法,在另一个线程下运行某些其他方法。我希望能够向robot对象发送移动命令,让执行该命令的线程睡眠持续毫秒,然后停止移动,但我希望能够调用stop方法并中断执行移动的线程。非常感谢您的帮助

public class robotTest
{

    public static void main(String[] args) throws InterruptedException
        {
            Robot robot = new Robot(); //Instantiate new Robot object
            robot.forward(255, 100, Robot.DIRECTION_RIGHT, 10); //Last argument representing duration
            Thread.sleep(5000); //Wait 5 seconds
            robot.stop(); //Stop movement prematurely

        }

}

如果我理解正确,那么是的,您可以从任何给定线程对对象调用方法。但是,要使其以无bug的方式工作,robot类必须是。

如果我理解正确,那么是的,您可以从任何给定线程调用对象上的方法。但是,要使其以无bug的方式工作,robot类必须是。

确保对robot的所有调用都来自一个线程,一个扩展线程的类,该线程是您创建的,具有进行调用的权限。将此方法添加到调用中

注意:这段代码远非完美。但它可能会给你一些想法,你可以在你的应用程序中使用

public void stop() throws NoPermissionException {

    checkStopPermission(); // throws NoPermissionException

    // rest of stop here as normal

}

/**
 * Alternatively you could return a boolean for has permission and then throw the NoPermissionException up there.
 */
private void checkStopPermission() throws NoPermissionException() {
    try {
        Thread t = Thread.currentThread();
        RobotRunnableThread rrt = (RobotRunnableThread)t; // may throw cast exception

        if(!rrt.hasPermission(RobotRunnableThread.STOP_PERMISSION)) { // assume Permission enum in RobotRunnableThread
            throw new NoPermissionExeception();
        }
    } catch(Exception e) { // perhaps catch the individual exception(s)?
        throw new NoPermissionException();
    }
}

确保所有对Robot的调用都来自一个线程,一个您创建的具有调用权限的类扩展线程。将此方法添加到调用中

注意:这段代码远非完美。但它可能会给你一些想法,你可以在你的应用程序中使用

public void stop() throws NoPermissionException {

    checkStopPermission(); // throws NoPermissionException

    // rest of stop here as normal

}

/**
 * Alternatively you could return a boolean for has permission and then throw the NoPermissionException up there.
 */
private void checkStopPermission() throws NoPermissionException() {
    try {
        Thread t = Thread.currentThread();
        RobotRunnableThread rrt = (RobotRunnableThread)t; // may throw cast exception

        if(!rrt.hasPermission(RobotRunnableThread.STOP_PERMISSION)) { // assume Permission enum in RobotRunnableThread
            throw new NoPermissionExeception();
        }
    } catch(Exception e) { // perhaps catch the individual exception(s)?
        throw new NoPermissionException();
    }
}

当你实例化一个机器人来处理移动时,你必须启动一个新的后台线程。线程会坐在那里,等待来自forward或stop的信号,然后执行适当的操作

您必须使用信号量、等待句柄或其他线程间通信元素来同步线程

浪费最多CPU的最不健壮的解决方案是伪代码,因为我有一段时间没有使用Java,可能与.NET API混合使用:

public class Robot implements IRunnable {
    public Robot() {
       new Thread(this).Start();
    }

    private int direction = 0;
    private int duration = 0;
    private bool go = false;

    public void Run() {
        DateTime moveStartedAt;
        bool moving = false;
        while(true) {
            if(go) {
                if(moving) {
                    // we are already moving
                    if((DateTime.Now - moveStartedAt).Seconds >= duration) {
                        moving = false;
                    }
                } else {
                    moveStartedAt = DateTime.Now;
                    moving = true;
                }
            } else {
                moving = false;
            }
        }
    }

    public void forward(int direction, int duration) {
        this.direction = direction;
        this.duration = duration;
        this.go = true;
    }

    public void stop() {
        this.go = false;
    }
}
以上代码应该修改为Java,以获得更好的答案

此代码有什么问题:

Run方法消耗一个完整的内核,它没有休眠 呼叫停止,然后立即向前,可能会导致比赛状态。跑步还没有看到停止,但你已经给了它另一个向前 Run无法退出 您可以调用forward以重定向已在进行的移动 其他人?
当你实例化一个机器人来处理移动时,你必须启动一个新的后台线程。线程会坐在那里,等待来自forward或stop的信号,然后执行适当的操作

您必须使用信号量、等待句柄或其他线程间通信元素来同步线程

浪费最多CPU的最不健壮的解决方案是伪代码,因为我有一段时间没有使用Java,可能与.NET API混合使用:

public class Robot implements IRunnable {
    public Robot() {
       new Thread(this).Start();
    }

    private int direction = 0;
    private int duration = 0;
    private bool go = false;

    public void Run() {
        DateTime moveStartedAt;
        bool moving = false;
        while(true) {
            if(go) {
                if(moving) {
                    // we are already moving
                    if((DateTime.Now - moveStartedAt).Seconds >= duration) {
                        moving = false;
                    }
                } else {
                    moveStartedAt = DateTime.Now;
                    moving = true;
                }
            } else {
                moving = false;
            }
        }
    }

    public void forward(int direction, int duration) {
        this.direction = direction;
        this.duration = duration;
        this.go = true;
    }

    public void stop() {
        this.go = false;
    }
}
以上代码应该修改为Java,以获得更好的答案

此代码有什么问题:

Run方法消耗一个完整的内核,它没有休眠 呼叫停止,然后立即向前,可能会导致比赛状态。跑步还没有看到停止,但你已经给了它另一个向前 Run无法退出 您可以调用forward以重定向已在进行的移动 其他人?
我建议使用ExecutorService实例化Robot类,您可以使用它异步移动。向您的服务提交移动请求,并使用返回的Future来“停止”移动请求

class Robot{
    final ExecutorService movingService = Executors.newSingleThreadExecutor();
    private volatile Future<?> request; //you can use a Deque or a List for multiple requests
    public void forward(int... args){
         request = movingService.submit(new Runnable(){
               public void run(){
                      Robot.this.move(args);
               }
         });
    }
    public void stop(){
       request.cancel(true);
    }

}

我建议使用ExecutorService实例化Robot类,您可以使用它异步移动。向您的服务提交移动请求,并使用返回的Future来“停止”移动请求

class Robot{
    final ExecutorService movingService = Executors.newSingleThreadExecutor();
    private volatile Future<?> request; //you can use a Deque or a List for multiple requests
    public void forward(int... args){
         request = movingService.submit(new Runnable(){
               public void run(){
                      Robot.this.move(args);
               }
         });
    }
    public void stop(){
       request.cancel(true);
    }

}

到目前为止,我对线程的接触非常有限。我知道使用线程需要什么,但是我不确定如何将对象上的特定方法调用定向到在该对象的构造函数中创建的特定线程。到目前为止,我对线程的接触非常有限。我知道使用线程需要什么,但是我不确定如何将对象上的特定方法调用定向到在该对象的构造函数中创建的特定线程。通过扩展RobotRunnableThread,您可以调用任何实例的停止?通过创建具有给定权限的新RobotRunnableThread,然后,当您尝试调用stop时,它将检查该线程的权限。如果该线程是RRT,并且该线程具有STOP_权限,则STOP将成功。否则你会得到一个NoPermExc。这不太可能是运行时异常-您必须在那里处理它。这也是开发人员在没有适当权限的情况下不要使用stop的线索。通过扩展RobotRunnableThread,您可以调用任何实例的stop?通过创建具有给定权限的新RobotRunnableThread,然后当您尝试调用stop时,它将检查该线程的权限。如果那根线
如果是RRT,并且线程具有STOP_权限,则STOP将成功。否则你会得到一个NoPermExc。这不太可能是运行时异常-您必须在那里处理它。这也将是一条线索,提醒开发者在没有适当许可的情况下不要使用stop。你允许它转义构造函数。你允许它转义构造函数。