0

我有一个监视键盘和鼠标输入的线程。当用户单击我程序中的按钮时,它会激活该线程,然后当用户输入特定组合时,它会在下面的示例代码中调用方法 test()。所以很明显,线程在这个 test() 方法中时不能监视我的输入,所以 spacePressed 永远不会变成真的,因为这个线程在完成之前不能调用它的另一个方法。

 public void test()
{
    spacePressed = false; 
    while(!spacePressed)
    {
        pasteAtCursorLocation("Test");
        sleepy(1000);
    }
}

那么我可以创建另一个线程来监视输入,并且当按下空格时,它会返回 true 到特定的函数调用。所以它会做我想要的吗?

public void test()
{
    SpaceWatcher sw = new SpaceWatcher();
    sw.start();
    while(!sw.SpacePressed())
    {
        pasteAtCursorLocation("Test");
        sleepy(1000);
    }
}

但这会经常调用 SpaceWatcher 吗?那就是 space watch 是否有足够的时间在空间输入调用之间观察输入?

编辑: pasteAtCursorLocation 就像它说的那样,困倦地调用 Thread.sleep(ms)

4

2 回答 2

0

也许您应该将该test()方法移动到一个新线程并spacePressed从事件处理程序中操作共享字段。

这样,您将拥有一个后台线程,它会发挥一些作用,直到变量变为 false 并且事件处理程序由操作系统驱动。

请注意,使用线程监视键盘和鼠标通常不是一个好主意;操作系统发送给您的事件已经是异步的。在一个特殊的线程中等待他们就像两次做同样的事情。

而是使用响应事件处理程序发送的“事件”的工作线程。查看队列

事件处理程序:

if( spaceWasPressed( keyboardEvent ) ) {
    queue.put( new SpaceWasPressed() );
}

工作线程:

while( queue.poll( 1, TimeUnit.SECONDS ) == null ) {
    pasteAtCursorLocation("Test");
}
于 2013-02-05T14:57:02.823 回答
0

睡眠 1000 毫秒对于计算机来说是一个非常非常长的时间,因此在这之间有足够的时间来做其他事情。该SpacePressed()函数只会返回一个布尔值,这是一件非常便宜的事情。

您的方式是正确的方式(当事情变得比您正在做的事情更复杂时,还有很多其他方式)让线程对他人做出反应。spacePressed但是在线程之间共享数据(在这种情况下)时,您必须牢记同步。它们需要同步。这可以通过使用synchronized关键字来完成。另一种选择是声明spacePressed volatile,这只能在非常特殊的情况下使用(例如仅更改一次的单个标志,或者如果您不在乎是否错过了 true-false-true 更改)。

于 2013-02-05T14:59:49.810 回答