java – Do threads share the same memory address as a method of an object?

Question:

I searched here on the OS but I didn't find anything like the question I have.

I have a Java program that makes use of Threads .

public class Objeto
{
   int i;

   public Objeto() { i = 0; }

   public void Foo()
   {
       i++;
       System.out.println("Aqui " + i);
   }
}

public class MinhaClasse
{
   int a;
   Objeto obj;

   public MinhaClasse()
   {
       a = 0;
       obj = new Objeto();
       while(a < 5)
       {
           Runnable task = () -> {
               FacaAlgo();
           };
           new Thread(task).start();
           a++;
       }
   }

   public void FacaAlgo()
   {
       obj.Foo();
   }
}

Problem
When I instantiate an object of class MinhaClasse 5 threads will be started that execute the same method ( FacaAlgo() ) of that object, and that it calls another method of another object ( obj.Foo() ). I would like to know if, in this concurrency of threads, by default , one thread waits for the other to enter and exit the FacaAlgo() method or do I have to put synchronized ?

Answer:

Threads by definition share the same memory space, that is, the current program memory. To have separate memory, you would have to create another process.

This means that all objects in a program can be accessed by any thread and it's up to you to control this, which you can do by not sharing an object between threads or ensuring that object modifications are atomic operations .

In your code, you share the object obj = new Objeto(); between all threads .

Java does not synchronize access to shared objects by default, and with good reason, because there are many valid cases where one or more methods of an object can be accessed concurrently.

A simple and less efficient solution for your case would be to synchronize the FacaAlgo method:

public synchronized void Foo()
{
    i++;
    System.out.println("Aqui " + i);
}

A more efficient solution, which does not make use of explicit synchronization, would be to use an object that is thread-safe , that is, whose access is safe for concurrent use and does not need to be synchronized.

An example with AtomicInteger :

public class Objeto {
   private AtomicInteger i = new AtomicInteger(0);

   public void foo() {
       System.out.println("Aqui " + i.incrementAndGet());
   }
}

public class MinhaClasse {
   public MinhaClasse() {
       final Objeto obj = new Objeto();
       for (int a = 0; a < 5; a++) {
           new Thread(obj::foo).start();
       }
   }
}

Note that I've changed its implementation a bit to keep it in the standard Java style and with best practices, namely:

  • Method names start with lowercase – except constructors.
  • Braces opening on the same line as the method/class/block.
  • Variables in the smallest possible scope (local) as they do not need to belong to the instance.
  • Variables that should not be changed are final . In the case of obj , it would already be implicitly final because it's implicitly passed to lambda, so it's better to make it explicit.
  • Method is passed by reference instead of creating a lamba that calls a local method and then calls the method on the other object.
Scroll to Top