我有一个监视键盘和鼠标输入的线程。当用户单击程序中的按钮时,它会激活此线程,然后当用户输入特定组合时,它会调用下面示例代码中的方法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经常有效吗?太空观察是否有足够的时间来观察空间输入的调用之间的输入?
编辑:pasteAtCursorLocation就像它说的那样,并且困了调用Thread.sleep(ms)
答案 0 :(得分:0)
也许您应该将test()
方法移动到新线程并从事件处理程序中操作共享字段spacePressed
。
这样,你就会有一个后台线程,它会做一些魔法,直到变量变为false并且事件处理程序由操作系统驱动。
请注意,使用线程观看键盘和鼠标通常不是一个好主意;操作系统发送给您的事件已经异步。在一个特殊的线程中等待他们就像两次做同样的事情。
而是使用工作线程来响应事件处理程序发送的“事件”。 Look into queues
事件处理程序:
if( spaceWasPressed( keyboardEvent ) ) {
queue.put( new SpaceWasPressed() );
}
工作人员主题:
while( queue.poll( 1, TimeUnit.SECONDS ) == null ) {
pasteAtCursorLocation("Test");
}
答案 1 :(得分:0)
对于计算机来说,睡眠1000毫秒是一个非常长的时间,因此有足够的时间来做其他事情。 SpacePressed()
函数只返回一个布尔值,这是一件非常便宜的事情。
你的方式是一种正确的方式(当事情变得比你正在做的更复杂时还有许多其他的方式)让线程对其他人做出反应。但是,在线程之间共享数据(在本例中为spacePressed
)时,您必须牢记同步。他们需要同步。这可以使用synchronized关键字来完成。另一种选择是声明spacePressed
volatile,这只能用于非常特殊的情况(例如只更改一次的单个标志,或者如果你错过了一个真假则不在乎-true change)。