Alternative to spinlock

烈酒焚心 提交于 2019-12-03 09:10:39

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();
}

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:

while( !hasPerformedAction() ) {
    (sleep a bit here)
}

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.

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:

SwingUtils.invokeLater(actionToInvoke);

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 to notify() it back into wakefulness once the action has been performed.

There are some classes for that in java.util.concurrent.locks. Have a look at Class LockSupport

Regards Mike

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!