有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程Java使用对象作为监视器,那个对象不是太重了吗?

我在Java语言规范17.1中读到:

"Each object in Java is associated with a monitor, which a thread can lock or unlock."

为什么一定?这难道不会使java对象太重吗?我不知道为什么像字符串这样的对象自然应该是监视器

编辑:

我仔细考虑了一下,是的,Java有一个关键字synchronized,因为每个对象都可以有一个同步方法,所以有必要将每个对象关联到监视器

但这似乎不是一个很好的解决方案,通常一个类需要多个互斥体,除了非常简单的pojo类


共 (5) 个答案

  1. # 1 楼答案

    基本问题是假设每个对象都内置了某种类型的Monitor,等待某些代码使用它。实际上,大多数对象从未用作监视器,因此在使用监视器之前不必创建监视器。与其将此功能实现为每个对象都有一个private Monitor monitor字段,不如将其实现为具有全局HashMap<object, Monitor> monitors字段的JVM

    一种可能的实现是:每当输入synchronized块时,JVM都会在映射(monitors)中查找同步对象。如果它找到它,它就会让监视器使用。如果找不到它,它将进入一个专门用于地图的关键部分。然后它会再次查找该对象,因为在上一次检查和进入临界段之间,可能有另一个线程创建了该对象。如果它仍然不在那里,它将为同步对象创建监视器并离开关键部分

  2. # 2 楼答案

    没有那么重。物品很便宜

    我同意任何对象都可以是锁的概念是相当混乱的。许多人认为synchronized(obj)保护obj不被并发访问。如果我们将锁与状态分开,那么这种误解就不太可能发生

    java内存模型中的文本并没有显示使用任意对象或任何对象作为同步原语的任何重要性。使用对象实现此目的可能是一种经济的设计

    它还可以使用整数作为锁synchronized(493725)实际上,由于每个对象在内部都与一个整数(其地址)相关联,JVM可能会这样做。没有同步对象的开销为零

    使用java。util。并发类,如果您不喜欢它,您就不再需要这样的synchronized(obj)

  3. # 3 楼答案

    线程同步对于确保正确的结果是必要的,因为它们可能处于竞速状态

    嗯,如果它没有LCD或CRT显示器那么重,那就好了

  4. # 4 楼答案

    这是一种非常聪明的方法,可以使几乎所有的东西都是线程安全的。我认为重量级有点主观;例如,在Java中,对象只获得一个应通知的等待队列,而使用synchronize显式地指定互斥

    C#使用了类似的方法来加强线程安全性,因此显然MS也认为这是一个非常聪明的解决方案。替代方案是什么?手写信号量和互斥量?在Java中,这将是一场噩梦,因为大多数生产级应用程序(即服务器、服务等)都是多线程的。让语言为你做所有那些艰难/无聊的事情有点棒

  5. # 5 楼答案

    您的假设中有一些事实,在经典著作《实践中的Java并发》(由大师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.

    (第2.4章:带锁的保护状态)