简体   繁体   English

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

[英]Stop execution of a thread by calling another thread

I have a thread that watches for keyboard and mouse input. 我有一个监视键盘和鼠标输入的线程。 When the user clicks a button in my program it activates this thread, and then when the user inputs a specific combination it calls the method test() in the example code below. 当用户单击程序中的按钮时,它会激活该线程,然后,当用户输入特定的组合时,它将在下面的示例代码中调用方法test()。 So obviously the thread cannot watch for my input while it is in this test() method so spacePressed will never become true because this thread cannot call another one of its methods until this has finished. 因此,很明显,线程处于此test()方法中时无法监视我的输入,因此spacePressed永远不会变为true,因为此线程在完成此操作之前无法调用其方法中的另一个方法。

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

So could I create another thread that also watches for input and when the space is pressed it return true to a specific function call. 所以我可以创建另一个也监视输入的线程,当按下空格时,它将返回true到特定的函数调用。 So that it does do what I desire? 这样就可以满足我的要求了吗?

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

But will this call SpaceWatcher to often to be effective? 但是,这将使SpaceWatcher经常有效吗? That is will space watch ever have enough time to watch for input between the calls to it for the space input? 那就是太空守望者是否有足够的时间来监视两次太空调用之间的输入?

EDIT: pasteAtCursorLocation does just as it says, and sleepy calls Thread.sleep(ms) 编辑:pasteAtCursorLocation就像它所说的那样,并且困倦地调用Thread.sleep(ms)

Maybe you should move the test() method to a new thread and manipulate the shared field spacePressed from the event handler. 也许您应该将test()方法移至新线程并从事件处理程序中操纵共享字段spacePressed

That way, you would have a background thread which does some magic until the variable becomes false and the event handler is driven by the OS. 这样,您将拥有一个后台线程,该线程会做一些魔术,直到变量变为false且事件处理程序由OS驱动。

Note that it's usually not a good idea to use a thread to watch keyboard and mouse; 注意,使用线程监视键盘和鼠标通常不是一个好主意。 the events sent to you by the OS are already asynchronous. 操作系统发送给您的事件已经是异步的。 Waiting for them in a special thread is like doing the same thing twice. 在特殊线程中等待它们就像在做相同的事情两次。

Instead use worker threads which respond to "events" sent by the event handler. 而是使用响应事件处理程序发送的“事件”的工作线程。 Look into queues . 调查队列

Event handler: 事件处理程序:

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

Worker thread: 工作线程:

while( queue.poll( 1, TimeUnit.SECONDS ) == null ) {
    pasteAtCursorLocation("Test");
}

Sleeping for 1000 ms is a very very long time for a computer, so there is plenty of time to do other stuff in between. 睡眠1000毫秒对于计算机而言是非常长的时间,因此在这之间有足够的时间执行其他操作。 The SpacePressed() function will only return a boolean, this is a really cheap thing to do. SpacePressed()函数只会返回一个布尔值,这是一件非常便宜的事情。

Your way is a correct way (there are many others when things get more complex than what you are doing) to have threads react to others. 您的方法是一种正确的方法(当事情变得比您做的事情更复杂时,还有很多其他方法)让线程对其他人做出反应。 But you must bear in mind synchronization when sharing data (in this case spacePressed ) between threads. 但是在线程之间共享数据(在这种情况下为spacePressed )时,必须牢记同步。 They need to be synchronized. 它们需要同步。 This can be done by using the synchronized keyword. 这可以通过使用synced关键字来完成。 Another option is to declare spacePressed volatile , this can only be used in very particular cases (such as a single flag that is changed only once or if you don't care if you miss a true-false-true change). 另一个选择是将spacePressed声明spacePressed volatile ,这只能在非常特殊的情况下使用(例如,仅更改一次的单个标志,或者如果您不在乎是否错过了true-false-true的更改)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM