好吧,我现在已经搜索了一整天,但没有结果。也许有人可以帮助它。
我正在尝试以编程方式在我的java程序中生成一个关键的“按住”状态。让我解释一下情况:
我经常听一个活动。考虑2个事件'A'和'B'。如果发生事件A,我想按住键盘键(X),如果发生事件'B',我想释放键(X)。现在最重要的是,这一切都必须是一个副流程,所以即使A出现,我也可以听B事件。
我尝试制作一个单独的线程,在其中创建一个无限循环,在java中使用'Robot'按键,但事实证明这是实现这一目标的最低效方式,因为它消耗了60%以上的CPU。我尝试通过更改状态来实现此目的,但似乎没有找到限制按键的方法,只有在我想要的时候才能更改。
如果可能的话,我会很感激没有任何无限循环的解决方案,因为我已经使用1来监听事件发生。 (建议欢迎)
这是我的线程代码:
public class KeyPress implements Runnable {
public String command;
public void run() {
try {
Robot r = new Robot();
while (true) {
//System.out.println(command);
if (command.equals("up")) {
r.keyPress(KeyEvent.VK_UP);
r.delay(20);
r.keyRelease(KeyEvent.VK_UP);
} else if (command.equals("finish")) {
break;
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
在我的主类中,像往常一样创建线程的实例。 此外,如果有人可以解释这一点 - 我删除或注释
System.out.println(command);
语句(如代码所示),此线程停止工作。如果我添加它,它的工作原理。虽然这个问题是次要的,因为它仍然是一个不可行的解决方案。
答案 0 :(得分:1)
嗯,经过漫长而累人的尝试来解决这个问题,我想我可能有一个解决方案。
首先,我每次活动创建一个帖子' A'发生了,虽然它和以前一样。当活动' B'发生,我打断线程,这使它退出。由于这些事件' A'和' B'或者,这适用于CPU使用问题。
另一个优化,可能是必须编写print()语句的问题的答案,我将变量command
设为volatile
。正如here所解释的那样,编译器优化很可能是我面临的问题。
以下是这些更改后的代码:
public class KeyPress implements Runnable {
public volatile String command;
public void run() {
try {
Robot r = new Robot();
while (command.equals("up") && !Thread.currentThread().isInterrupted()) {
r.keyPress(KeyEvent.VK_UP);
r.delay(20);
}
} catch (Exception e) {
System.out.println(e);
}
}
}
我希望这可以帮助某人,并且有人可以提供有关如何改进它的建议。
答案 1 :(得分:0)
Observer pattern可能是一个很好的解决方案。
不要在线程中循环。使用这样的通知和监听模式:
听取命令:
class RobotObserver implements Observer{
private Robot r = new Robot();
@Override
public void update(Observable o, Object arg) {
String command=arg.toString();
if (command.equals("up")) {
r.keyPress(KeyEvent.VK_UP);
r.delay(20);
r.keyRelease(KeyEvent.VK_UP);
} else if (command.equals("finish")) {
System.out.println(command);
}
}
}
通知听众:
Observable observable = new Observable();
observable.addObserver(new RobotObserver());
observable.notifyObservers("up");
observable.notifyObservers("finish");
PS:类Observer
和Observable
都在java.util
包中。