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
There are some classes for that in
java.util.concurrent.locks
. Have a look at ClassLockSupport
Regards Mike
There's a gui in your tags, so I'll assume that the action is done in the GUI.
The "recommended" way to do this kind of thing is for the main thread to put itself to sleep (perhaps using
wait()
) and for the GUI action tonotify()
it back into wakefulness once the action has been performed.The java tutorials have a good lesson on concurrency in java:
http://java.sun.com/docs/books/tutorial/essential/concurrency/
If you are going to be modifying UI from another thread, you will want to remember to do:
What you've written is called busy looping, which you should never do.
You may want to keep doing that, but at least sleep a bit as to not be busy looping, which still wouldn't be that great:
Another way to do it would to enqueue the user actions on a blocking queue: then you could simply be using a queue.take and the queue implementation would take care of the issue for you.
And another way would be to use a callback to be notified of the user actions.
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:
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
Thread 2