When thread tA call tB.join() its causes not only waits for tB to die or tA be interrupted itself but create happens-before relation between last statement in tB and next statement after tB.join() in tA thread.
It means program
class App {
// shared, not synchronized variable = bad practice
static int sharedVar = 0;
public static void main(String[] args) throws Exception {
Thread threadB = new Thread(() -> {sharedVar = 1;});
threadB.start();
threadB.join();
while (true)
System.out.print(sharedVar);
}
}
Always print
>> 1111111111111111111111111 ...
But program
class App {
// shared, not synchronized variable = bad practice
static int sharedVar = 0;
public static void main(String[] args) throws Exception {
Thread threadB = new Thread(() -> {sharedVar = 1;});
threadB.start();
// threadB.join(); COMMENT JOIN
while (true)
System.out.print(sharedVar);
}
}
Can print not only
>> 0000000000 ... 000000111111111111111111111111 ...
But
>> 00000000000000000000000000000000000000000000 ...
Always only '0'.
Because Java Memory Model don't require 'transfering' new value of 'sharedVar' from threadB to main thread without heppens-before relation (thread start, thread join, usage of 'synchonized' keyword, usage of AtomicXXX variables, etc).