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 of a program can be accessed by any thread and it’s up to you to control that, which can be done not sharing an object between threads or ensuring that modifications to the object are atomic operations.
In your code, you share the object obj = new Objeto();
of all the threads.
Java does not synchronize by default access to shared objects 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 method FacaAlgo
:
public synchronized void Foo()
{
i++;
System.out.println("Aqui " + i);
}
A more efficient solution, which makes no use of explicit synchronization, would be to use an object that is thread-safe, that is, whose access is secure 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 changed its implementation a little to keep it within the standard Java style and with best practices, namely:
- Method names start with lowercase - except constructors.
- Keys opening on the same line as 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
, he would already be implicitly final
because it is implicitly passed to the lambda, so it is better to make explicit.
- Method is passed by reference instead of creating a lamba that calls a local method to then call the method in the other object.
Thanks for the expensive answer, but only one thing in one of his notes: "Brackets (actually keys) opening in the same line of the method/class/block" be standard of some language is slutty stuff dude, this is programming style kkkkkk'
– Christian Felipe
@Christianfelipe You won’t see any serious Java developers writing keys in another line, except on legacy systems over a decade old. This is the official standard of Oracle, of Google, of Android and of all modern Ides. Of course you can adopt the style you want, the only problem is having to change if you work on a real project :)
– utluiz
Just one question: you said that the obj variable is passed by reference. Is that right? Shouldn’t the correct reference be passed by value? Should the same be for the correct foo method? Whereas java does not support passing by reference
– Murillo Henrique
Is there no "reference" in java? Living and learning, my understanding was wrong this time
– user28595
@Murillohenrique I did not say that the variable is passed by reference, but that it is passed a reference to the object. I am not using here the terminology of passing for reference or value that exists in other languages. When in Java you talk about passing a reference, that’s it. To say that you passed a reference by value is redundant in a world where pointers don’t exist and to do otherwise is impossible.
– utluiz
@utluiz I believe that the ideal is to avoid this type of terminology because as our colleague commented up there, he did not know that passing by reference is not supported in java, The reason for this confusion is that many start with the C language and there it is possible to reference a variable, however I found its argument very valid, it is reductive because it already understands exactly what you said, I would just avoid talking like this but I understood your point. Thank you for the material on the Atomicinteger, very interesting.
– Murillo Henrique
@Murillohenrique Unfortunately there is no way to avoid the terminology because it has no other term. In Java references are references, all are passed by value, but remain references. I cannot say that you passed the object, I cannot say that you passed a pointer to the object, nor that you passed a value pointing to the object. I know it’s a common confusion, but unfortunately there are many conflicting terms between the languages. Another thing, passing methods by reference is also correct, since the original name of the resource added in Java 8 is Method Reference.
– utluiz
@utluiz Very good your explanation, I will read more about the Method Reference, thank you very much.
– Murillo Henrique