我正在为机器人制作界面。我的机器人类具有包括移动,停止移动和读取传感器数据的方法。如果可能的话,我希望某些方法在给定的线程下运行,而某些其他方法在另一个下运行。我希望能够发送命令移动到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
}
}
答案 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以获得更好的答案)
此代码有什么问题: