简体   繁体   English

锁定为实体成员与同步(最佳实践)

[英]Lock as a member of entity vs synchronized (best practice)

Let's say I have an EntityPool.假设我有一个 EntityPool。 After I get an entity from the pool, I need to modify the entity in a thread-safe way.从池中获取实体后,我需要以线程安全的方式修改实体。 So I see 2 choices:所以我看到了 2 个选择:

1) Using synchronized: 1)使用同步:

Entity e = pool.getById(id); 
synchronized (e) {
    // modifying e
}

2) Add a lock to the Entity class and use it: 2) 为实体 class 添加一个锁并使用它:

Entity e = pool.getById(id);
Lock l = e.getLock();
try {
    l.lock();
    // modifying e
} finally {
    l.unlock();
}

I've heard that I should avoid using "synchronized" keyword.我听说我应该避免使用“同步”关键字。 Should I use lock instead?我应该改用锁吗? But it seems weird to me that the Entity class should know anything about synchronization.但在我看来,实体 class 应该知道任何关于同步的事情,这对我来说似乎很奇怪。

There are different use cases to justify both approaches.有不同的用例来证明这两种方法的合理性。

1 is common. 1 很常见。 It uses the object itself as a lock, so any synchronized methods on the entity as well as any other synchronized access are serialized.它使用 object 本身作为锁,因此实体上的任何同步方法以及任何其他同步访问都被序列化。 It also does not require making the Entity class lock-aware.它也不需要使实体 class 具有锁定意识。

2 requires that you embed a lock into the entity class. 2 要求您将锁嵌入到实体 class 中。 This allows you to control synchronization in a more fine-grained manner.这允许您以更细粒度的方式控制同步。 You can, for instance, use the lock to control access to a subset of the object state while keeping methods accessing other parts of the object lock-free.例如,您可以使用锁来控制对 object state 子集的访问,同时保持访问 object 其他部分的方法无锁。

If you know what you're doing, there's no need to avoid the synchronized keyword.如果您知道自己在做什么,就没有必要避免使用 synchronized 关键字。 That can be said for locks as well.锁也可以这样说。

Use 'synchronized' if your usage follows lexical scope.如果您的用法遵循词汇 scope,请使用“同步”。 Synchronization starts when you enter a synchronized method or the body of a synchronized {…} clause, and ends when you leave it.同步在您输入synchronized方法或synchronized {…}子句的主体时开始,并在您离开时结束。

By contrast, locking and unlocking can be applied to arbitrary sequences of actions.相比之下,锁定和解锁可以应用于任意的动作序列。 You can, for example, acquire the lock in a call to some sort of 'startSomething' method, and release the lock in a later call to an 'endSomething' method.例如,您可以在调用某种“startSomething”方法时获取锁定,并在稍后调用“endSomething”方法时释放锁定。 The cost of this is your need to ensure correctness.这样做的代价是您需要确保正确性。

tl;dr - use synchronized unless it clearly doesn't work for your use case. tl; dr - 使用synchronized除非它显然不适用于您的用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM