有多少个线程可以同时调用对象的非同步方法?

所以,假设我有一个带有方法m的类X. 方法m 不是同步的,它不需要,因为它不会真正改变X类型的对象x的状态。

在某些线程中,我调用这样的方法:xm()。 所有这些线程都使用相同的对象x。

这个方法(方法m)可以同时在对象x上调用多少个线程? 可能是这个方法被调用,比方说,100个线程是我的应用程序的瓶颈?

谢谢。

其他人已经回答了你的直接问题。

我想澄清一些可能是你的误解的东西……如果是,那就是危险的

方法m不是同步的,它不需要,因为它不会真正改变X类型的对象x的状态。

这不是一个充分的条件。 不改变状态的方法通常也需要同步。

假设你有一个带有简单getter和setter的类Test:

public class Test { private int foo; public int getFoo() { return foo; } public synchronized void setFoo(int foo) { this.foo = foo; } } 

getter线程安全吗?

  • 根据你的规则,是的。
  • 实际上,没有。

为什么? 因为除非调用getFoosetFoo的线程正确同步, getFoo()在调用setFoo(...)之后调用setFoo(...)可能会看到foo的陈旧值。

这是一个令人讨厌的案例,几乎所有的时间你都会侥幸逃脱。 但偶尔,两次通话的时间将会让虫子咬你。 这种错误很可能会在测试中出现问题,并且在生产过程中很难再现。


在没有同步的情况下从多个线程访问对象状态绝对安全的唯一情况是当状态被声明为final ,构造函数不会发布该对象。

如果你有更多的线程处于可运行状态而不是物理内核,你最终会因为上下文切换而浪费时间……但这就是它。 如果它们之间没有协调,那些线程正在执行相同方法的事实是无关紧要的。

记住线程和实例之间的区别。 一个是执行另一个是数据。 如果数据不在某种锁定机制或某些资源约束下,那么访问仅受底层基础结构可以运行的线程数量的限制。 这是一个系统(jvm实现+ OS +机器)限制。

是的,一个不同步的方法并不“关心”有多少线程正在调用它。 它是一个纯粹被动的实体,当一个新线程进入它时没有什么特别的事情发生。

也许让一些人感到困惑的一件事是方法使用的“自动”存储。 此存储在线程堆栈上分配,不需要该方法的主动参与。 方法的代码简单地给出了一个指向存储的指针。

(许多,许多月以前,情况并非如此。当调用方法时,“自动”存储是从堆中分配的,或者方法维护了一个“自动”存储区域的列表。但是这种模式可能在40年前消失了,我怀疑是否存在仍然使用它的任何系统。而且我确信没有JVM使用该方案。)

如果一个线程获得了其他人需要的资源并将其保留在长时间运行的操作中,那么您就会遇到瓶颈。 如果这不是您的方法的情况,我不知道您将如何体验瓶子。

这是一个理论上的问题,还是你在一个真实的应用程序中观察行为的速度比你想象的要慢?

最好的答案是获取一些数据并查看。 运行测试并监控它。 做一名科学家。