25

I would like to known if each instance of a class has its own copy of the methods in that class?

Lets say, I have following class MyClass:

public MyClass {

    private String s1;

    private String s2; 

    private String method1(String s1){
    ...
    }

    private String method2(String s2){
    ...
    }
}

So if two differents users make an instance of MyClass like:

MyClass instanceOfUser1 = new MyClass();
MyClass instanceOfUser2 = new MyClass();

Does know each user have in his thread a copy of the methods of MyClass? If yes, the instance variables are then thread-safe, as long as only the instance methods manipulate them, right?

I am asking this question because I often read that instance variables are not thread-safe. And I can not see why it should be like that, when each user gets an instance by calling the new operator?

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
Horace
  • 1,198
  • 2
  • 17
  • 31
  • Are you asking about each thread having its own instance of `MyClass` or one instance of `MyClass` with different methods for each thread? – Jeffrey Jul 26 '13 at 16:16
  • No instance variables are inherently thread safe. If two threads can modify a reference to the same object, then you need to implement some sort of synchronization – Joel Jul 26 '13 at 16:16
  • 9
    You're really confused. Thread-safety is about state. And state is about fields, not methods. The thread-safety of your class depends entirely on how the fields s1 and s2 are used by the methods. Not having their body makes the question impossible to answer. – JB Nizet Jul 26 '13 at 16:17
  • Making MyClass immutable would mean this question does not arise, of course. – Mark Chorley Jul 26 '13 at 16:18
  • 2
    *I am asking this question because I often read that instance variables are not thread-safe.* Since your question was tagged as java-ee (not sure why), you can see a real example of having non-static variables that are prone to thread-safety problems in Servlets, as explained here: [How do servlets work? Instantiation, session variables and multithreading](http://stackoverflow.com/q/3106452/1065197), read the article-like answer and the bottom section: **Threadsafety**. Note that you must understand how the component behaves to really know if its fields are prone to multithread issues. – Luiggi Mendoza Jul 26 '13 at 16:21
  • @joel how to know if my mobect can be modified by two or more threads? – user1169587 Mar 08 '21 at 06:07

6 Answers6

20

Each object gets its own copy of the class's instance variables - it's static variables that are shared between all instances of a class. The reason that instance variables are not necessarily thread-safe is that they might be simultaneously modified by multiple threads calling unsynchronized instance methods.

class Example {
    private int instanceVariable = 0;

    public void increment() {
        instanceVariable++;
    }
}

Now if two different threads call increment at the same then you've got a data race - instanceVariable might increment by 1 or 2 at the end of the two methods returning. You could eliminate this data race by adding the synchronized keyword to increment, or using an AtomicInteger instead of an int, etc, but the point is that just because each object gets its own copy of the class's instance variables does not necessarily mean that the variables are accessed in a thread-safe manner - this depends on the class's methods. (The exception is final immutable variables, which can't be accessed in a thread-unsafe manner, short of something goofy like a serialization hack.)

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
  • 2
    Wait, so you're saying the `instanceVariable` field is not safe from conflicting reads/writes if a completely new instance is used in each thread? This *is* the scenario the OP is talking about, no? – Asad Saeeduddin Sep 10 '14 at 17:34
  • @AsadSaeeduddin Obviously, every new instance is a brand new space allocated on the heap just for that object. Thread-safety is about how you access a single object which comes down to how that object's members are accessed - are they static or instance variables, if later, how is the invoked method guaranteeing thread-safety. In other words, how do you guarantee this - "completely new instance is used in each thread"? – user1234 Apr 07 '21 at 15:14
11

Issues with multi-threading arise primarily with static variables and instances of a class being accessed at the same time.

You shouldn't worry about methods in the class but more about the fields (meaning scoped at the class level). If multiple references to an instance of a class exist, different execution paths may attempt to access the instance at the same time, causing unintended consequences such as race conditions.

A class is basically a blueprint for making an instance of an object. When the object is instantiated it receives a spot in memory that is accessed by a reference. If more than one thread has a handle to this reference it can cause occurrences where the instance is accessed simultaneously, this will cause fields to be manipulated by both threads.

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
11

'Instance Variables are not thread safe' - this statement depends on the context. It is true, if for example you are talking about Servlets. It is because, Servlets create only one instance and multiple threads access it. So in that case Instance Variables are not thread safe.

In the above simplified case, if you are creating new instance for each thread, then your instance variables are thread safe.

Hope this answers your question

Ravi Vasamsetty
  • 403
  • 2
  • 6
6

A method is nothing but a set of instructions. Whichever thread calls the method, get a copy of those instructions. After that the execution begins. The method may use local variables which are method and thread-scoped, or it may use shared resources, like static resources, shared objects or other resources, which are visible across threads.

rocketboy
  • 9,573
  • 2
  • 34
  • 36
5

Each instance has its own set of instance variables. How would you detect whether every instance had a distinct "copy" of the methods? Wouldn't the difference be visible only by examining the state of the instance variables?

In fact, no, there is only one copy of the method, meaning the set of instructions executed when the method is invoked. But, when executing, an instance method can refer to the instance on which it's being invoked with the reserved identifier this. The this identifier refers to the current instance. If you don't qualify an instance variable (or method) with something else, this is implied.

For example,

final class Example {

  private boolean flag;

  public void setFlag(boolean value) {
    this.flag = value;
  }

  public void setAnotherFlag(Example friend) {
    friend.flag = this.flag;
  }

}

There's only one copy of the bytes that make up the VM instructions for the setFlag() and setAnotherFlag() methods. But when they are invoked, this is set to the instance upon which the invocation occurred. Because this is implied for an unqualified variable, you could delete all the references to this in the example, and it would still function exactly the same.

However, if a variable is qualified, like friend.flag above, the variables of another instance can be referenced. This is how you can get into trouble in a multi-threaded program. But, as long as an object doesn't "escape" from one thread to be visible to others, there's nothing to worry about.

erickson
  • 265,237
  • 58
  • 395
  • 493
1

There are many situations in which an instance may be accessible from multiple classes. For example, if your instance is a static variable in another class, then all threads would share that instance, and you can get into big trouble that way. That's just the first way that pops into my mind...

dcsohl
  • 7,186
  • 1
  • 26
  • 44