所以,假设我有一个带有方法m的类X.方法m是 NOT 同步的,它不需要,因为它并没有真正改变X类型的对象x的状态。
在某些线程中,我调用这样的方法:x.m()。所有这些线程都使用相同的对象x。
这个方法(方法m)可以同时在对象x上调用多少个线程? 可能是这个方法被调用,比方说,100个线程是我的应用程序的瓶颈?
感谢。
答案 0 :(得分:3)
如果你有更多的线程处于可运行状态而不是物理内核,你最终会因为上下文切换而浪费时间......但这就是它。如果它们之间没有协调,那些线程正在执行相同方法的事实是无关紧要的。
答案 1 :(得分:3)
其他人已经回答了你的直接问题。
我想澄清一些可能的错误概念......如果是,那就是危险。
方法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线程安全吗?
为什么呢?因为除非调用getFoo
和setFoo
的主题正确同步,否则在调用getFoo()
后调用setFoo(...)
可能会看到foo
的陈旧值。< / p>
这是一个令人讨厌的案例,你几乎可以在任何时候逃脱它。但偶尔,两次通话的时间将会让虫子咬你。这种错误可能会在测试中出现问题,并且在生产过程中很难重现。
绝对安全地从多个线程访问对象状态而不进行同步的唯一情况是当状态被声明为final
时,构造函数不会发布该对象。
答案 2 :(得分:1)
记住线程和实例之间的区别。一个是执行另一个是数据。如果数据不在某种锁定机制或某些资源约束下,那么访问仅受底层基础结构可以运行的线程数量的限制。这是一个系统(jvm实现+ OS +机器)限制。
答案 3 :(得分:1)
是的,一个不同步的方法并不“关心”有多少线程正在调用它。它是一个纯粹被动的实体,当新线程进入它时没有什么特别的事情发生。
也许让一些人感到困惑的一件事是方法使用的“自动”存储。此存储在线程堆栈上分配,不需要该方法的主动参与。该方法的代码只是给出了一个指向存储的指针。
(许多,许多月前,情况并非如此。当调用方法时,“自动”存储是从堆中分配的,或者该方法维护了一个“自动”存储区域的列表。但是这种范式可能消失了40年前,我怀疑是否存在仍然使用它的系统。我确信没有JVM使用该方案。)
答案 4 :(得分:0)
如果一个线程获得了其他人需要的资源并将其保留在长时间运行的操作中,那么您就会遇到瓶颈。如果这不是您的方法的情况,我不知道您将如何体验瓶子。
这是一个理论问题,还是你在观察一个比你想象的运行速度慢的实际应用中的行为?
最好的答案是获取一些数据并查看。运行测试并监控它。做个科学家。