简体   繁体   English

私人锁对象和固有锁

[英]private lock object and intrinsic lock

When to prefer private lock object to synchronize a block over intrinsic lock(this)? 什么时候更喜欢私有锁对象而不是固有锁(this)同步块? Please cite the upshots of both. 请列举两者的结果。

private lock object:- 私人锁对象:-

Object lock =new Object();  
synchronized(lock)
{  }

intrinsic lock(this):- 固有锁(this):-

synchronized(this)
{  }

Using explicit lock objects can allow different methods to synchronize on different locks and avoid unnecessary contention. 使用显式lock对象可以允许不同的方法对不同的锁进行同步,并避免不必要的争用。 It also makes the lock more explicit, and can make it easier to search the code for blocks that use the lock. 这也使锁更加显式,并且可以更轻松地在代码中搜索使用该锁的块。

You probably don't want to do either, however! 但是,您可能既不想这样做! Find the appropriate class in java.util.concurrent and use that instead. 在java.util.concurrent中找到适当的类,然后改用该类。 :) :)

A private lock can be useful if you are doing some kind of lock sharding, ie, you need to only lock certain parts of your object while others can still be accessed by a different client. 如果您正在执行某种类型的锁分片,则私有锁可能很有用,例如,您只需要锁定对象的某些部分,而其他部分仍可以由其他客户端访问。

One simple parallel to understand this concept is a table lock in a database: if you are modifying one table, you acquire the lock on that single table, not the whole database, so the rest of the tables can be modified by other clients. 一个简单的理解这一概念的方法是数据库中的表锁:如果要修改一个表,则要获得该单个表而不是整个数据库的锁,因此其余表可以由其他客户端修改。 If you need to implement a similar logic but in a POJO you would use as many private locks as necessary. 如果您需要实现类似的逻辑,但是在POJO中,您将根据需要使用尽可能多的私有锁。

One downside of this approach is that your class gets cluttered with a lot of objects. 这种方法的一个缺点是您的类中到处都是很多对象。 This might be indication that you need to refactor it in a more granular set of classes with a simpler locking strategy but it all depends on your design and implementation. 这可能表明您需要使用更简单的锁定策略在更精细的类集中重构它,但这完全取决于您的设计和实现。

These are both using intrinsic locks. 它们都使用内在锁。 Your first example is using the intrinsic lock of lock , while the second is using the intrinsic lock of this . 你的第一个例子是使用的内部锁lock ,而第二个是使用的内部锁this The question is whether or not this is really what you want to lock on, which it often isn't. 问题是this是否真的是您要锁定的东西,而通常不是。

Consider the case, when you use synchronized(this) inside one of your methods. 考虑一种情况,当您在一种方法中使用synchronized(this) You have 2 objects of this class, and these objects reference some shared resource. 您有2个此类的对象,这些对象引用一些共享资源。 If you lock on this then you will not have mutual exclusivity to that resource. 如果锁定this那么您将不会互斥该资源。 You need to lock on some object that everything that can access the resource has access to. 您需要锁定所有可以访问该资源的对象都可以访问的对象。

Lock on this ONLY if the important resource is part of the class itself. 仅当重要资源是类本身的一部分时才锁定this属性。 Even then in some cases a lock object is better. 即使这样,在某些情况下,锁定对象还是更好的选择。 Also, if there's several different resources in your class, that do not need to be mutually exclusive as a whole, but individually, then you need several lock objects. 另外,如果您的类中有多个不同的资源,它们不需要在整体上互斥,而是可以互斥,那么您需要几个锁定对象。

The key is to really just know how synchronized works, and be mindful of what your code is actually doing 关键是真正只知道同步的工作原理,并注意代码的实际作用

Actually, using either won't make any difference, it is more about choice/style, API writers will lock on the Object -either by synchronized(this) or explicit synchronized on any Object method- , or use an internal monitor depends on sharing a resource, you might not want API users to access your internal lock or you might want to give the choice to API users to share the Object intrinsic lock. 实际上,使用两者不会有任何区别,更多的是关于选择/样式,API编写者将锁定Object - 通过sync(this)或在任何Object方法上显式同步-或使用内部监视器取决于共享资源,您可能不希望API用户访问您的内部锁,或者您可能希望让API用户选择共享对象固有锁。

Either way none of those choices are wrong, it is more about the intention of such lock. 无论哪种选择都不对,这更多是关于这种锁定的意图。

Read Java Concurrency in Practice , that will make you a master of concurrency and clarify many of those concepts, which sometimes are more related with the choice you make rather than correctness. 阅读《 实践中的Java并发性》 ,这将使您精通并发性,并阐明许多概念,这些概念有时与您所做的选择相关,而不是正确性。

Each object has only one intrinsic lock. 每个对象只有一个固有锁。

With the synchronized keyword: if you call two synchronized methods from the same object from two different threads, even-thought one thread could run method one and the other thread could run method two, that will not happen because both methods share the same intrinsic lock (which belongs to the object). 使用synced关键字:如果您从两个不同线程的同一对象中调用两个同步方法,则即使有一个想法可以运行一个方法,而另一个线程可以运行方法2,则不会发生,因为这两个方法共享相同的内在锁(属于对象)。 And according to that one thread will have to wait for the other thread to finish before it can acquire the intrinsic lock to run the other method. 并且据此,一个线程将必须等待另一线程完成,才能获取内部锁以运行另一种方法。

But if you use multiple locks , you will make sure that only one thread can access method one at a time and that only one thread can access method two at a time. 但是,如果使用多个锁 ,则将确保一次只有一个线程可以访问一个方法,并且一次只能有一个线程访问两个方法。 But you will allow that method one and method two can be accessed by one thread each at the same time and then reducing the time required for the operation. 但是您将允许一个线程可以同时访问方法一和方法二,从而减少了操作所需的时间。

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

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