Ketika utas tA memanggil tB.join (), penyebabnya tidak hanya menunggu tB untuk mati atau tA terputus, tetapi juga membuat hubungan sebelum-kejadian antara pernyataan terakhir di tB dan pernyataan berikutnya setelah tB.join () di utas tA.
Semua tindakan di utas terjadi sebelum utas lain berhasil kembali dari gabungan () di utas itu.
Itu berarti 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);
}
}
Selalu cetak
>> 1111111111111111111111111 ...
Tapi 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);
}
}
Dapat mencetak tidak hanya
>> 0000000000 ... 000000111111111111111111111111 ...
Tapi
>> 00000000000000000000000000000000000000000000 ...
Selalu hanya '0'.
Karena Java Memory Model tidak memerlukan 'mentransfer' nilai baru 'sharedVar' dari threadB ke utas tanpa heppens-sebelum relasi (permulaan thread, penggabungan thread, penggunaan kata kunci 'synchonized', penggunaan variabel AtomicXXX, dll).