Question

I am making a Java app which does something on a HotKey combination. I have an infinite while loop to wait for HotKey input to close, but it makes the app very CPU time costing.

Following is how my code looks in the simplest way:

static boolean isOpen = true;
void main()
{
    ....
    add SomeHotKeyListener();
    ....
    while(isOpen)
    {  }
    releaseResources();
}

void onHotKey(int hotKeyIdentifier)
{
    if(hotKeyIdentifier == something)
      do something;
    if(hotKeyIdentifier == something)
      isOpen = false;
}

I need a multi-threading approach to achieve this, or if someone has something better to fit in.

Était-ce utile?

La solution

I recommend you read about the synchronized keyword in Java. Just Google it, and you should find a ton of examples and tutorials.

This should solve your case:

static boolean isOpen = true;
static Object lock = new Object();
void main()
{
    ....
    add SomeHotKeyListener();
    ....
    synchronized(lock)
    {
        while(isOpen)
        {
            try {
                lock.wait()
            } catch(InterruptedException e) {
            }
        }
    }
    releaseResources();
}

void onHotKey(int hotKeyIdentifier)
{
    if(hotKeyIdentifier == something)
        do something;
    if(hotKeyIdentifier == something)
    {
        synchronized(lock)
        {
            isOpen = false;
            lock.notify();
        }
    }
}

Autres conseils

Infinite while loop can consume quite a lot of system resource. Using wait and notify is recommended. Also you have to declare your boolean volatile as otherwise there is no guarantee that the changes made by one thread is picked up by the other. Below is an example which does something in a separate thread and until interrupted by the calling thread based on a user input (an enter in this case). See also the example from Oracle here

import java.util.Scanner;

public class WaitTest implements Runnable {

private volatile boolean shutdown = false;

public static void main(String[] args) {

    WaitTest w = new WaitTest();

    new Thread(w).start();

    System.out.println("Press any key to interrupt");
    Scanner sc = new Scanner(System.in);
    sc.nextLine();

    w.triggerShutDown();
}

@Override
public void run() {
    while (!shutdown) {
        synchronized (this) {
            try {
                System.out.println("doing some silly things");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    System.out.println("Server shutdown successfully");
}

public synchronized void triggerShutDown() {
    this.shutdown = true;
    notify();
}
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top