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

时间:2011-03-13 03:08:35

标签: java multithreading

我正在为机器人制作界面。我的机器人类具有包括移​​动,停止移动和读取传感器数据的方法。如果可能的话,我希望某些方法在给定的线程下运行,而某些其他方法在另一个下运行。我希望能够发送命令移动到robot对象,让线程执行它睡眠duration毫秒然后停止移动,但我想要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

        }

}

4 个答案:

答案 0 :(得分:2)

如果我正确理解你,那么你可以从任何给定的线程调用对象上的方法。但是,为了使其能够以无错误的方式工作,机器人类需要thread safe

答案 1 :(得分:2)

我建议使用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);
    }

}

答案 2 :(得分:0)

确保您对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();
    }
}

答案 3 :(得分:0)

当您实例化一个可以处理移动的Robot时,您必须启动一个新的后台线程。线程会坐在那里,等待来自前进或停止的信号并做适当的事情。

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

浪费最多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()方法使用一个完整的Core(它没有睡眠)
  • 立即调用stop()然后forward()会导致竞争状态(Run()还没有看到停止,但你已经给了另一个前锋了)
  • Run()无法退出
  • 您可以调用forward()来重定向正在进行的移动
  • 其他?