通过调用另一个线程来停止执行线程

时间:2013-02-05 14:41:41

标签: java multithreading

我有一个监视键盘和鼠标输入的线程。当用户单击程序中的按钮时,它会激活此线程,然后当用户输入特定组合时,它会调用下面示例代码中的方法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)

2 个答案:

答案 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)。