简体   繁体   English

Java使用对象作为监视器,那不是很重的对象吗?

[英]Java uses object as monitor, isn't that object too heavy weight?

I read this in Java language Spec 17.1: 我是用Java语言规范17.1阅读的:

"Each object in Java is associated with a monitor, which a thread can lock or unlock." “ Java中的每个对象都与一个监视器关联,线程可以锁定或解锁监视器。”

Why necessarily? 为什么一定要这样? Doesn't that make java object too heavy weight? 这不是使Java对象太重吗? I've no idea why a Object like, say, a string, should be naturally a monitor! 我不知道为什么像字符串这样的对象自然应该是监视器!

EDIT: 编辑:

I think it over and yes, Java has a keyword synchronized , because EVERY object could have a synchronized method, so it's necessary to associate EVERY object a Monitor. 我想一想,是的,Java有一个关键字sync ,因为每个对象都可以有一个同步方法,因此有必要将每个对象与Monitor关联。

But still this seems not a very good solution, usually you need more that one mutex for one class, except for that pojo classes that's really very simple. 但这仍然不是一个很好的解决方案,通常一个类需要一个互斥量,除了pojo类非常简单之外。

There is some truth in your assumptions, in the classical book "Java Concurrency in Practice" (written by the gurus Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, Doug Lea) they write: 您的假设中有一些道理,在经典著作“ Java Concurrency in Practice”(由权威专家Brian Goetz,Tim Peierls,Joshua Bloch,Joseph Bowbeer,David Holmes,Doug Lea撰写)中,他们写道:

The fact that every object has a built-in lock is just a convenience so that you needn't explicitly create lock objects. 每个对象都有内置锁的事实只是一种方便,因此您无需显式创建锁对象。 In retrospect, this design decision was probably a bad one: not only can it be confusing, but it forces JVM implementors to make tradeoffs between object size and locking performance. 回想起来,这个设计决定可能是一个糟糕的决定:不仅会造成混乱,而且会迫使JVM实现者在对象大小和锁定性能之间进行权衡。

(chapter 2.4.: Guarding State with Locks) (第2.4章:带锁的防护状态)

Your fundamental problem is in assuming that every object has some sort of Monitor built into it, waiting for it to be used by some code. 您的基本问题是假设每个对象都内置有某种Monitor ,等待其被某些代码使用。 In reality, most objects are never used as a monitor, so the monitors don't have to be created until they are used. 实际上,大多数对象从不用作监视器,因此在使用监视器之前不必创建它们。 Rather than implementing this feature as every object having a private Monitor monitor field, think of it as being implemented as the JVM having a global HashMap<object, Monitor> monitors . 与其将这个功能实现为每个具有private Monitor monitor字段的HashMap<object, Monitor> monitors不如将其视为具有全局HashMap<object, Monitor> monitors的JVM来实现。

A possible implementation is this: Whenever a synchronized block is entered, the JVM looks up the synchronized object in the map ( monitors ). 可能的实现方式是:每当输入synchronized块时,JVM都会在映射( monitors )中查找同步对象。 If it finds it, it gets the monitor to use. 如果找到它,则可以使用监视器。 If it doesn't find it, it enters a critical section dedicated to the map. 如果找不到,则会进入地图专用的关键部分。 It then looks up the object again because another thread may have created it between the previous check and entering the critical section. 然后,它再次查找该对象,因为在上一次检查和进入关键部分之间可能已经有另一个线程创建了该对象。 If it's still not there, it creates the monitor for the synchronized object and leaves the critical section. 如果仍然不存在,它将为同步对象创建监视器,并离开关键部分。

It's a pretty smart way to make virtually everything thread-safe. 这是使几乎所有线程安全的一种非常聪明的方法。 I think heavy weight is somewhat subjective; 我认为沉重的体重有些主观; in Java, for example, the object only gains a notifiable wait queue, while specifying mutual exclusion is explicitly done with synchronize . 在Java中,例如,对象只获得一项须予公布等待队列,同时指定互斥明确与完成synchronize

C# uses a similar method to enforce thread safety, so clearly MS also thought it was a pretty clever solution. C#使用类似的方法来增强线程安全性,因此显然MS也认为这是一个非常聪明的解决方案。 The alternative is what? 替代是什么? Hand-written semaphores and mutexes? 手写信号量和互斥量? In Java, that would be a nightmare, considering most production-level apps (ie servers, services, etc) have to be multi-threaded. 在Java中,考虑到大多数生产级应用程序(即服务器,服务等) 必须是多线程的,这将是一场噩梦。 Having the language do all that tough/boring stuff for you is kind of awesome. 让语言为您完成所有困难/无聊的工作真是太棒了。

Thread synchronization is necessary to ensure correct outcome as their may be racing condition. 线程同步对于确保正确的结果是必要的,因为它们可能处于竞争状态。

Well, if it is not as heavy as a LCD or CRT monitor, it would be fine? 好吧,如果它不如LCD或CRT显示器那么重,那还好吗?

not that heavy in weight. 没那么重 objects are cheap. 对象很便宜。

I agree that the concept that any object can be a lock is quite confusing. 我同意任何对象都可以是锁的概念非常令人困惑。 many people thinks that synchronized(obj) protects the obj from being accessed concurrently. 许多人认为, synchronized(obj)可以防止同时访问obj if we have separate locks from states, this misconception is less likely. 如果我们将锁与国家/地区分开,则这种误解的可能性较小。

not text in java memory model shows any importance of using arbitrary object, or any object, as synchronization primitives. Java内存模型中的文字不显示使用任意对象或任何对象作为同步原语的任何重要性。 maybe it's economical design to use objects for this purpose. 为此目的使用对象也许是一种经济的设计。

it could as well use integers as locks. 它也可以将整数用作锁。 synchronized(493725) actually since each object is associated with an integer internally (its address), JVM probably does this. synchronized(493725)实际上是因为每个对象在内部都与一个整数(其地址)相关联,因此JVM可能synchronized(493725) There's zero overhead for objects that are not being synchronized upon. 未同步的对象的开销为零。

with java.util.concurrent classes, you don't ever need such synchronized(obj) any more, if you dislike it. 使用java.util.concurrent类,即使您不喜欢它,也不再需要此类synchronized(obj)

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

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