在synchronized语句参数中,variable
Lock = Any()
做什么呢?synchronized
只允许在给定的时间有一个线程进入主体,因此,为什么我们不使用this
而不是Lock = Any()
,因为this
指的是伴随对象本身?
我读到它是与java monitors
有关的东西,但是,我不明白。
companion object{
...
private val LOCK = Any()
operator fun invoke(context: Context) = instance ?:synchronized(LOCK){
...
}
}
1条答案
按热度按时间nhhxz33t1#
看一下the Java docs中关于锁和同步的内容。(如果你只熟悉Kotlin,Java是它的基础,它足够接近你的想法)
基本上,* synchronization * 允许您控制对某些东西的访问,方法是一次只允许一个线程访问。(或 monitor),如果你使用它,一次只能有一个线程获得它。所以你可以用它把一个对象变成一种访问令牌--如果另一个线程想要获得那个锁,它必须等到第一个线程处理完它。
因此,您可以使用它来阻止代码的执行,方法是在这些访问令牌后面将其控制。(未指定标记),或者如果将
synchronized
* 语句 * 与this
一起使用,在这两种情况下,它都使用包含对象的锁来控制对该方法/块中代码的访问。(这并不阻止线程访问非同步代码(如其他方法)或同步块之前的代码。)但这是有限制的--这意味着访问该对象示例中任何同步代码的所有程序都需要获取相同的令牌。如果您有多个同步块,它们彼此真正分离,并且可以安全地并发运行,那么共享一个锁是低效的--它会毫无理由地阻碍其他线程。
但是如果你为每个任务都有一个单独的锁对象,那么为任务A获取一个锁对象并不会影响为任务B获取一个锁对象。通过使用单独的锁,你可以使你的同步更精细。但是你仍然要小心--如果任务A实际上涉及到调用任务B中的东西,反之亦然,你可能会最终遇到两个线程都被阻塞的情况。等待另一个任务完成。在这种情况下,两个任务实际上应该使用共享锁,因此无论启动哪个任务,都可以保证完成它。
至于为什么这个例子(有一个同步块)使用显式锁定对象而不是
this
,我不确定。单独锁定对象的另一个好处是,它可以在一个类的不同示例之间共享,甚至可以在不同的类之间共享,如果它们都在可能相互干扰的地方工作的话。由于companion object
基本上是一个单一的,类似于static
对象,您可以通过将其用作锁来获得好处而且
LOCK
对象是私有的,所以它不能被其他类用作锁--它在这里纯粹是内部使用的。(通过他们的示例方法),也许编码人员认为synchronized(LOCK)
比synchronized(Companion)
读起来更好,也许他们计划以后添加其他粒度锁,或者它们只是用于显式地创建锁定对象,以便始终鼓励您考虑要锁定的对象。在Kotlin中这样做可能还有其他原因,但希望这能让您了解为什么首先要创建不同的锁定对象