同步块中的静态与非静态锁定对象 [英] Static versus non-static lock object in synchronized block

查看:171
本文介绍了同步块中的静态与非静态锁定对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试可视化和理解同步


  1. 使用 静态锁定对象(代码A)之间有什么区别和同步块 非静态锁定对象(代码B)

  2. 在实际应用中有何不同?

  3. 对方不会有什么陷阱?

  4. 确定使用哪一个的标准是什么?

  1. What are the differences between using a static lock object (code A) and a non-static lock object (code B) for a synchronized block?
  2. How does it differ in practical applications?
  3. What are the pitfalls one would have that the other wouldn't?
  4. What are the criteria to determine which one to use?

代码A

public class MyClass1 {
  private static final Object lock = new Object();
  public MyClass1() {
    //unsync
    synchronized(lock) {
      //sync
    }
    //unsync
  }
}

代码B

public class MyClass2 {
  private final Object lock = new Object();
  public MyClass2() {
    //unsync
    synchronized(lock) {
      //sync
    }
    //unsync
  }
}

注意

上面的代码显示了构造函数,但您可以在静态方法和非静态方法中讨论行为的不同之处。另外,当synchronized块修改静态成员变量时使用静态锁是否有利?

The above code shows constructors, but you could talk about how the behavior is different in a static method and a non-static method too. Also, would it be advantageous to use a static lock when the synchronized block is modifying a static member variable?

我已经在这个问题,但不清楚不同的使用场景是什么。

I already looked at answers in this question, but it's not clear enough what the different usage scenarios are.

推荐答案

区别很简单:如果锁定对象位于 static 字段中,那么 MyClass * 分享该锁定(即没有两个对象可以同时锁定该对象)。

The difference is simple: if the locked-on object is in a static field, then all instances of MyClass* will share that lock (i.e. no two objects will be able to lock on that object at the same time).

如果该字段是非静态的,然后每个实例都有自己的锁,因此只有同一对象上的方法的调用才会相互锁定。

If the field is non-static, then each instance will have its own lock, so only calls of the method on the same object will lock each other.

使用静态锁定对象时:


  • 线程1调用 o1.foo()

  • 线程2调用 o1.foo(),必须等待线程1完成

  • 主题3 ca lls o2.foo()必须等待线程1(可能还有2)才能完成

  • thread 1 calls o1.foo()
  • thread 2 calls o1.foo(), will have to wait for thread 1 to finish
  • thread 3 calls o2.foo(), will also have to wait for thread 1 (and probably 2) to finish

使用非静态锁定对象时:

When you use a non-static lock object:


  • 线程1调用 o1.foo()

  • 线程2调用 o1.foo() ,必须等待线程1完成

  • 线程3调用 o2.foo(),它可以继续,而不是注意线程1和2

  • thread 1 calls o1.foo()
  • thread 2 calls o1.foo(), will have to wait for thread 1 to finish
  • thread 3 calls o2.foo(), it can just continue, not minding thread 1 and 2

您需要哪一项取决于您尝试保护的数据类型使用您的synchronized块。

Which one of those you'll need depends on what kind of data you try to protect with your synchronized block.

根据经验,您希望lock-object具有相同的 static - 比操作值更高。因此,如果您仅操作非静态值 ,则需要非静态锁定对象。如果你只操作静态值 ,你需要一个静态锁对象。

As a rule of thumb, you want the lock-object to have the same static-ness than the operated-on value. So if you manipulate non-static values only, you'll want a non-static lock object. If you manipulate static values only, you'll want a static lock object.

当你操作静态和非静态值,然后它会变得复杂。 easy 方式只是使用静态锁定对象,但这可能会增加synchronized块的大小,而不是绝对必要,并且可能需要比预期更多的锁争用。在这些情况下,您可能需要静态和非静态锁定对象的组合。

When you manipulate static and non-static values, then it'll become complicated. The easy way would be to just use a static lock object, but that might increase the size of the synchronized-block more than absolutely necessary and might need to more lock contention than desired. In those cases you might need a combination of static and non-static lock objects.

在您的特定情况下,您在构造函数中使用锁定,该锁定只会被执行每个实例一次,所以非静态锁对象在这里没有任何意义。

In your particular case you use the lock in the constructor, which will only ever be executed once per instance, so a non-static lock-object doesn't make any sense here.

这篇关于同步块中的静态与非静态锁定对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆