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

3

I looked here in the OS only that I did not find anything like the doubt I have.

I have a Java program that uses 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 it will start 5 threads 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 thread competition, by default, one thread waits for the other to enter and exit the FacaAlgo() method or do I have to synchronized ?

    
asked by anonymous 20.06.2016 / 17:21

2 answers

6

Threads by definition share the same memory space, that is, the memory of the current program. 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 is up to you to control this, which can be done not sharing an object between threads or ensuring that object modifications are atomic operations .

In your code, you share the obj = new Objeto(); object 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 use 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 your implementation a bit to leave it within the standard Java style and with best practices, namely:

  • Method names begin with lowercase - except constructors.
  • Keys opening on the same line as method / class / block.
  • Variables in the smallest (local) scope, since 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 is implicitly passed to lambda, so it's best to make 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.
21.06.2016 / 06:17
3

Your case has a peculiarity: you are passing the same Runnable to all Thread s. This Runnable is associated with the current MinhaClasse object% ( this ) using the FacaAlgo method. It would be another story if we were talking about different objects. You do need synchronization, in cases like that.

    
20.06.2016 / 17:51