螺旋锁的替代品

时间:2010-01-31 21:01:25

标签: java user-interface synchronization spinlock

我使用以下螺旋锁方法:

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

setHasPerformedAction(false);

return getActionPerfomed();

这基本上等待用户执行操作然后返回它。目前有些东西在继续之前请求用户回答,这就是我等到收到输入的原因。然而,我想知道这是否效率低,如果我们等待一段时间(即< = 30秒),它会减慢运行此应用程序的电脑的速度。有没有其他替代方法使用这种方法,即锁定,信号量,如果是这样的语法是什么?

谢谢,

阿里

5 个答案:

答案 0 :(得分:9)

事实上,这不仅效率低下,甚至无法保证工作,因为您所显示的代码中没有“发生在前”的边缘。要创建happens-before edge,您需要执行以下操作之一:

  1. 访问易变变量
  2. 在共享资源上进行同步
  3. 使用并发工具锁。
  4. 正如另一条评论中所提到的,最简单的解决方案,只是为了确保你的标志是一个易变的变量,并简单地在你的循环中抛出一个短暂的睡眠。

    但是,最好的办法是在共享变量上同步/ wait / notify。

    您需要阅读的方法是waitnotify。有关如何使用这些内容的更好说明,请阅读this article。示例代码段如下所示;

    主题1

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

    主题2

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

答案 1 :(得分:2)

你写的东西叫忙碌循环,你永远不应该这样做。

你可能想继续这样做,但至少要睡一会儿不要忙着循环,这仍然不会那么好:

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

另一种方法是将用户操作排入阻塞队列:然后您只需使用 queue.take ,队列实现就会为您解决问题。< / p>

另一种方法是使用回调来通知用户操作。

答案 2 :(得分:2)

java教程对java中的并发性有很好的教训:

http://java.sun.com/docs/books/tutorial/essential/concurrency/

如果您要从另一个线程修改UI,您将需要记住:

SwingUtils.invokeLater(actionToInvoke);

答案 3 :(得分:1)

您的代码中有 gui ,因此我假设该操作已在GUI中完成。

执行此类操作的“推荐”方法是让主线程让自己进入睡眠状态(可能使用wait()),并将GUI操作转移到notify(),一旦它返回到清醒状态行动已经完成。

答案 4 :(得分:1)

java.util.concurrent.locks中有一些类。看看课程LockSupport

问候迈克