【问题标题】:Synchronized Methods in JavaJava中的同步方法
【发布时间】:2025-12-29 06:40:10
【问题描述】:

只是想检查以确保我理解这一点。同步方法不会创建线程,对吗?它只是确保没有其他线程在调用此方法,而同一进程中的一个线程(即 JVM)正在使用它,对吧?

【问题讨论】:

  • 同步线程就像卫生间的隔间——请一次一个人。

标签: java multithreading synchronized


【解决方案1】:

同步方法不会创建线程,对吧?

没错。

它只确保没有其他线程在调用此方法 同一进程(即 JVM)中的一个线程正在使用它,对吧?

没错。

如需了解更多信息,请阅读Synchronized Methods。我也推荐阅读Java Concurrency in Practice

【讨论】:

  • 关于您的第二个问题,它不会阻止其他线程调用该特定方法。相反,它将阻塞其他线程并将它们放入队列中。一旦锁可用,下一个线程将获得锁并获得对该方法的访问权限。
  • 是的,这就是我的意思。它就像一个Semaphore,只是它不是。 Java 中的synchronized 关键字允许线程进入所谓的Monitor,这很像信号量。我不记得在学校有什么区别,除了信号量在 C 中使用,而监视器需要 C++ 和 Java 等面向对象的语言。
  • 但是,老实说,synchronized 关键字确实让我想起了 Mutex 锁,而不是 Semaphore,因为似乎只有一个线程可以一次进入“关键区域”,而其他线程必须等待它。 Java中不能指​​定允许进入监视器的线程数?
【解决方案2】:

这基本上是正确的。调用同步方法不会产生新线程。它只是让其他线程在尝试为该对象的该实例调用 any 其他同步方法时阻塞。

要记住的关键是一个类的所有同步方法都使用相同的锁。

【讨论】:

    【解决方案3】:

    是的。

    同步块还有另一个重要作用:当一个线程进入一个同步块时,它会看到访问该块(或与相同锁同步的另一个块)的前一个线程对值所做的更改。

    基本上在多核 cpu 上,每个线程在其核心上作为自己的内存缓存:每个核心都有相同变量的副本,它们的值在每个核心上可能不同。 当存在同步操作时,JVM 确保将变量值从一个内存缓存复制到另一个。进入同步块的线程然后会看到前一个线程“更新”的值。

    正如 mre 所建议的,如果您真的想了解多线程和学习最佳实践,Java Concurrency in Practice 是一个很好的参考。

    【讨论】:

    • 是的,所以每个核心都有自己的内存缓存是线程而不是进程,对吧?我听说有人告诉我每个核心只有一个进程,但我认为你是对的。我还记得我的大学教授告诉我,在任何时间点只有一个进程可以访问单个 CPU。
    • 嗯,这很复杂。线程和进程几乎是一回事。不同之处在于线程与姊妹线程共享一些公共内存,而进程只有自己的内存。公共内存很有用,因为线程基本上可以与之通信。我认为大多数操作系统的线程必须定义为进程的子进程。如果你有一个双核 cpu,在任何时间点,2 个进程、2 个线程或 1 个线程 + 1 个进程都在运行。你教授说的是单核CPU时代。
    • 如果是这样的话,那么多核与多CPU有什么不同呢? CPU有自己的内存,对吧? CPU 上使用的内存似乎只用于一个进程。但是,我不是计算机工程师,我真的在这里猜测。
    • 确实,多 CPU 与多核几乎相同。每个内核都有一些非常快的本地缓存(通常只有几千 kB)。整个 cpu 有一个较慢的全局缓存,由所有内核共享(通常为几 MB)。像这样拥有多层缓存会使同步变得复杂,但它确实提高了性能。至于线程,不同的线程可能运行在不同的核上,但也可以运行在同一个核上。