有 Java 编程相关的问题?

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

java多线程编程按住键

好吧,我已经搜索了一整天,但没有结果。也许有人能帮上忙

我试图以编程方式在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);

语句(如代码中所示),此线程停止工作。如果我加上这个,它就行了。虽然这个问题是次要的,因为它仍然是一个不可行的解决方案


共 (2) 个答案

  1. # 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);
        }
    }
    }
    

    我希望这能帮助一些人,并且有人能提供如何改进的建议

  2. # 2 楼答案

    也许是个好办法

    不要在线程中循环。使用如下通知和侦听器模式:

    听命令:

    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:ObserverObservable都在包java.util