如果线程类只有一个实例,是否需要同步?

时间:2013-12-06 08:49:52

标签: java multithreading synchronization

参考这个主题(How to pause Thread execution),Peter Knego说:

  

循环必须在同步块内。

但如果只有一个实例,我就没有看到同步点。

在另一种情况下,如果线程类有多个实例并且它们正在使用不同的变量,那么循环是否需要同步。

实际上,我使用线程(有多个实例)编写了一些程序而没有考虑同步,它们工作正常。

4 个答案:

答案 0 :(得分:1)

您必须同步对共享状态的任何访问权限。如果所有实例都访问本地存储,则它们是线程安全的。如果您的方法是线程安全的,则它们不需要同步。如果你有一个静态(例如全局)资源,并在多个线程中修改它,那么这可能是非线程安全的(当然不包括原子操作)。

答案 1 :(得分:0)

答案是

使用synchronized,wait()和notify()。

  1. 在要停止的线程中创建原子标志(例如布尔字段)。 Stoppable线程在循环中监视此标志。循环必须在synchronized块内。
  2. 当您需要停止线程(按钮单击)时,您可以设置此标志。
  3. 线程看到标志已设置并在公共对象(可能是其自身)上调用wait()
  4. 如果要重新启动线程,请重置标记并调用commonObject.notify()
  5. 您不能在对象上调用wait()或notify,除非您在其监视器上获得锁定。并将其置于同步块内是一种方法。

答案 2 :(得分:0)

这是因为waitnotifycondition variable的一部分,并且在没有同步的情况下使用它们导致一般用例导致竞争条件

正常的使用等待方式是

synchronized(this){
    while(someCondition())
       wait();//while loop is needed to combat spurious wakeups
}

然后用

唤醒它
synchronized(this){
    adjustCondition();
    notify();
}

如果您没有同步条件,那么您将参加比赛

您刚刚测试someCondition()并获得了true所以您需要等待。但在你有机会到另一个线程执行adjustCondition();notify();

之前

但是第一个线程仍将进入wait()(因为条件已经被检查)并且可能导致死锁

答案 3 :(得分:-1)

线程监视器需要在您的情况下同步。这仅适用于实际的等待调用,因为它需要这样做。我建议有一个特殊的等待对象,以防止意外同步。

final static Object threadPauseMonitor = new Object();
// ...
while (shouldPause.get()) {
  synchronized(threadPauseMonitor) {
    threadPauseMonitor.wait();
  }
}

其中shouldPause是AtomicBoolean。请注意while以应对可能发生的恶意虚假唤醒