Search code examples
javauser-interfacesynchronizationspinlock

Alternative to spinlock


I am using the following spinlock approach:

while(!hasPerformedAction()){
    //wait for the user to perform the action
    //can add timer here too
}

setHasPerformedAction(false);

return getActionPerfomed();

this basically waits for a user to perform an action and then returns it. Currently something requests an answer from the user before continuing, this is why I wait until input is received. However I was wondering if this is inefficient and if we are waiting for a while (i.e. <= 30 secs) will it slow down the pc that is running this app. Are there any other alternatives using this approach i.e. locks, semaphores if so what is the syntax?

Thanks,

Aly


Solution

  • In fact, not only is this inefficient, it is not even guaranteed to work, since there is no "happens-before" edge in the code that you are showing. To create a happens-before edge you need to do one of:

    1. Access a volatile variable
    2. Synchronise on a shared resource
    3. Use a concurrent utils lock.

    As mentioned in another comment, the easiest solution, is simply to ensure that your flag is a volatile variable, and simply throw a short sleep in your loop.

    However, the best thing to do would be to synchronize/wait/notify on a shared variable.

    The methods that you need to read up on are wait and notify. For a better description on how to use these, read this article. An example code snippet is shown below;

    Thread 1

    Object shared = new Object();
    startThread2(shared);
    synchronized (shared) {
      while (taskNotDone())
        shared.wait();
    }
    

    Thread 2

    // shared was saved at the start of the thread
    // do some stuff
    markTaskAsDone();
    synchronized (shared) {
      shared.notify();
    }