何时更喜欢私有锁对象来同步块而不是内在锁(this)?请引用两者的结果。
私有锁对象:-
Object lock =new Object();
synchronized(lock)
{ }
内在锁(这个): -
synchronized(this)
{ }
何时更喜欢私有锁对象来同步块而不是内在锁(this)?请引用两者的结果。
私有锁对象:-
Object lock =new Object();
synchronized(lock)
{ }
内在锁(这个): -
synchronized(this)
{ }
使用显式lock
对象可以允许不同的方法在不同的锁上同步,避免不必要的争用。它还使锁更加明确,并且可以更容易地在代码中搜索使用锁的块。
但是,您可能也不想这样做!在 java.util.concurrent 中找到适当的类并使用它。:)
实际上,使用两者都不会有任何区别,更多的是关于选择/风格,API编写者将锁定对象- 通过同步(this)或在任何对象方法上显式同步 -或使用内部监视器取决于共享一个资源,您可能不希望 API 用户访问您的内部锁,或者您可能希望让 API 用户选择共享对象内部锁。
无论哪种方式,这些选择都不是错误的,更多的是关于这种锁定的意图。
阅读Java Concurrency in Practice,这将使您成为并发大师并阐明其中许多概念,这些概念有时与您所做的选择有关,而不是与正确性有关。
如果您正在执行某种锁分片,则私有锁可能很有用,即您只需要锁定对象的某些部分,而其他客户端仍然可以访问其他部分。
理解这个概念的一个简单的平行是数据库中的表锁:如果您正在修改一个表,您将获得该单个表的锁,而不是整个数据库,因此其他表可以被其他客户端修改。如果您需要实现类似的逻辑,但在 POJO 中,您将根据需要使用尽可能多的私有锁。
这种方法的一个缺点是你的类会被很多对象弄得乱七八糟。这可能表明您需要使用更简单的锁定策略将其重构为一组更细粒度的类,但这完全取决于您的设计和实现。
这些都使用内在锁。您的第一个示例是使用 的内在锁lock
,而第二个示例是使用 的内在锁this
。问题是是否this
真的是你想要锁定的东西,而它通常不是。
synchronized(this)
当您在其中一种方法中使用时,请考虑这种情况。你有这个类的 2 个对象,这些对象引用了一些共享资源。如果您锁定,this
那么您将不会对该资源具有互斥性。您需要锁定可以访问该资源的所有对象都可以访问的某个对象。
this
仅当重要资源是类本身的一部分时才锁定。即便如此,在某些情况下,锁定对象会更好。此外,如果你的类中有几个不同的资源,它们不需要作为一个整体互斥,而是单独的,那么你需要几个锁对象。
关键是要真正了解同步的工作原理,并注意您的代码实际在做什么
每个对象只有一个内在锁。
使用 synchronized 关键字:如果您从两个不同的线程从同一个对象调用两个同步方法,即使一个线程可以运行方法一而另一个线程可以运行方法二,这不会发生,因为这两个方法共享相同的内在锁(属于对象)。根据这一点,一个线程必须等待另一个线程完成,然后才能获得内在锁来运行另一个方法。
但是如果你使用多个锁,你将确保一次只有一个线程可以访问方法一,并且一次只有一个线程可以访问方法二。但是您将允许一个线程同时访问方法一和方法二,从而减少操作所需的时间。