In the JMM, a thread starting another thread, and a thread join, both create happens-before edges. Given: main sets shared=42 (plain field), then calls t.start(); inside t the run() reads shared. Then main calls t.join() and reads result (plain field) written by t. Which visibility guarantees hold?
int shared; // plain
int result; // plain
Thread t = new Thread(() -> { use(shared); result = compute(); });
shared = 42;
t.start();
t.join();
int r = result;