简体   繁体   English

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

[英]How many threads can simultaneously invoke an unsynchronized method of an object?

So let's say I have a class X with a method m.因此,假设我有一个 class X,其方法为 m。 Method m is NOT synchronized and it doesn't need to be since it doesn't really change the state of the object x of type X.方法 m不是同步的,也不需要同步,因为它并没有真正改变 X 类型的 object x 的 state。

In some threads I call the method like this: xm().在某些线程中,我调用这样的方法:xm()。 All these threads use the same object x.所有这些线程都使用相同的 object x。

By how many threads can be this method (method m) called on object x simultaneously?这个方法(方法 m)可以同时在 object x 上调用多少个线程? Can be the fact that the method is called by, let's say, 100 threads a bottleneck for my application?可能是该方法被调用的事实,比如说,100 个线程是我的应用程序的瓶颈吗?

thanks.谢谢。

If you have more threads in the runnable state than you have physical cores, you'll end up wasting time by context switching... but that's about it.如果您在可运行的 state 中有比物理内核更多的线程,那么您最终会通过上下文切换浪费时间……但仅此而已。 The fact that those threads are executing the same method is irrelevant if there's no coordination between them.如果它们之间没有协调,那么这些线程正在执行相同的方法这一事实是无关紧要的。

Other's have answered your direct question.其他人已经回答了您的直接问题。

I'd like to clear up something that is could be a misconception on your part... and if it is, it is a dangerous one.我想澄清一些可能是你的误解......如果是,那是一个危险的。

Method m is NOT synchronized and it doesn't need to be since it doesn't really change the state of the object x of type X.方法 m 不是同步的,也不需要同步,因为它并没有真正改变 X 类型的 object x 的 state。

That is not a sufficient condition.这不是充分条件。 Methods that don't change state typically need to be synchronized too.不改变 state 的方法通常也需要同步。

Suppose that you have a class Test with a simple getter and setter:假设您有一个带有简单 getter 和 setter 的 class 测试:

public class Test {
    private int foo;

    public int getFoo() {
        return foo;
    }

    public synchronized void setFoo(int foo) {
        this.foo = foo;
    }
}

Is the getter thread-safe? getter 线程安全吗?

  • According to your rule, yes.按照你的规定,是的。
  • In reality, no.实际上,没有。

Why?为什么? Because unless the threads that call getFoo and setFoo synchronize properly, a call to getFoo() after a call to setFoo(...) may see a stale value for foo .因为除非调用getFoosetFoo的线程正确同步,否则在调用setFoo(...) getFoo()之后调用 getFoo() 可能会看到foo的陈旧值。

This is one of those nasty cases where you will get away with it nearly all of the time.这是您几乎所有时间都可以逃脱的那些令人讨厌的情况之一。 But very occasionally, the timing of the two calls will be such that the bug bites you.但非常偶尔,两次调用的时间安排会导致 bug 咬到你。 This kind of bug is likely to slip through the cracks of your testing, and be very difficult to reproduce when it occurs in production.这种错误很可能会从您的测试中溜走,并且在生产中发生时很难重现。


The only case where it absolutely safe to access an object's state from multiple threads without synchronizing is when the state is declared as final , AND the constructor doesn't publish the object.唯一可以绝对安全地从多个线程访问对象的 state 而不进行同步的情况是,当 state 被声明为final并且构造函数没有发布 ZA8CFDE6331BD59EB2AC96F8911C4B666 时。

Remember the difference between threads and instances.记住线程和实例之间的区别。 One is executing the other is data.一个是执行,另一个是数据。 If the data is not under some locking mechanism, or some resource constraints then the access is only limited by the number of threads that can run by the underlying infrastructure.如果数据不受某种锁定机制或某种资源限制,则访问仅受底层基础设施可以运行的线程数限制。 This is a system (jvm implementation + OS + machine) limitation.这是系统(jvm 实现 + OS + 机器)限制。

Yep, an unsynchronized method doesn't "care" how many threads are invoking it.是的,一个不同步的方法并不“关心”有多少线程在调用它。 It's a purely passive entity and nothing special occurs when a new thread enters it.它是一个纯粹的被动实体,当一个新线程进入它时没有什么特别的事情发生。

Perhaps one thing that confuses some people is the "auto" storage used by a method.也许让一些人感到困惑的一件事是一种方法使用的“自动”存储。 This storage is allocated on the thread's stack, and does not require the active participation of the method.这个存储是在线程的栈上分配的,不需要方法的积极参与。 The method's code is simply given a pointer to the storage.该方法的代码只是简单地给出了一个指向存储的指针。

(Many, many moons ago, it wasn't thus. Either the "auto" storage was allocated from heap when the method was called, or the method maintained a list of "auto" storage areas. But that paradigm disappeared maybe 40 years ago, and I doubt that there is any system in existence that still uses it. And I'm certain that no JVM uses the scheme.) (很多很多个月前,情况并非如此。在调用该方法时,“自动”存储是从堆中分配的,或者该方法维护了一个“自动”存储区域列表。但这种范式可能在 40 年前就消失了,我怀疑是否存在任何仍在使用它的系统。而且我确定没有 JVM 使用该方案。)

You'd have a bottleneck if one thread acquired a resource that others needed and held onto it for a long-running operation.如果一个线程获得了其他人需要的资源并持有它以进行长时间运行的操作,那么您将遇到瓶颈。 If that isn't the situation for your method, I don't see how you'll experience a bottle.如果这不是您的方法的情况,我不知道您将如何体验一瓶。

Is this a theoretical question, or are you observing behavior in a real application that's running more slowly than you think it should?这是一个理论上的问题,还是您正在观察实际应用程序中的行为,该应用程序的运行速度比您认为的要慢?

The best answer of all is to get some data and see.最好的答案是获取一些数据并查看。 Run a test and monitor it.运行测试并监控它。 Be a scientist.做一个科学家。

暂无
暂无

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

相关问题 多个线程同时向非同步的ArrayList对象添加元素会导致什么问题? - What are the possible problems caused by adding elements to unsynchronized ArrayList's object by multiple threads simultaneously? 我们可以同时从多个线程访问同一个实例的同步方法和非同步方法吗? - Can we Access Synchronized method and an unsynchronized method of same instance from multiple threads at the same time? 多个线程如何调用单例对象的方法并对它们起作用? - how multiple threads invoke singleton object's method and work on them? 如何使公共静态非同步getInstance()方法将私有静态引用变量的多个实例返回给对象? - How can I make a public static unsynchronized getInstance() method return multiple instances of a private static reference variable to an object? 如何从多个线程同时调用方法? - How to call a method simultaneously from multiple threads? 尽管对象被锁定,但未同步的方法仍然可以访问,为什么? - An unsynchronized method can still get access despite the object being locked, why? Java非同步线程,这个答案怎么会出现,怎么解释 - Java unsynchronized threads, how could this answer appear and how to explain it 如何同步两种方法,以防止它们同时被不同的线程访问,但是只允许一个方法的多个实例 - How to sync two methods to prevent them both being accessed by different threads simultaneously but allow as many instances of only one method 如何使用Reflection API调用对象上的方法? - How can I invoke a method on an object using the Reflection API? 为什么不同步的ArrayList对象添加方法行为不正确 - Why Unsynchronized ArrayList Object add method is not behaving properly
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM