Metode Thread.join () di Java

1. Ikhtisar

Dalam tutorial ini, kita akan membahas metode join () yang berbeda di kelas Thread . Kami akan membahas detail metode ini dan beberapa kode contoh.

Seperti metode wait () dan notify () , join () adalah mekanisme lain dari sinkronisasi antar-thread.

Anda dapat melihat sekilas tutorial ini untuk membaca lebih lanjut tentang wait () dan notify () .

2. Thread.join () Method

Metode gabungan ditentukan di kelas Thread :

public final void join () melempar InterruptedException

Menunggu utas ini mati.

Saat kita memanggil metode join () pada utas, utas pemanggil masuk ke status menunggu. Itu tetap dalam keadaan menunggu sampai utas yang direferensikan berakhir.

Kita dapat melihat perilaku ini pada kode berikut:

class SampleThread extends Thread { public int processingCount = 0; SampleThread(int processingCount) { this.processingCount = processingCount; LOGGER.info("Thread Created"); } @Override public void run() { LOGGER.info("Thread " + this.getName() + " started"); while (processingCount > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { LOGGER.info("Thread " + this.getName() + " interrupted"); } processingCount--; } LOGGER.info("Thread " + this.getName() + " exiting"); } } @Test public void givenStartedThread_whenJoinCalled_waitsTillCompletion() throws InterruptedException { Thread t2 = new SampleThread(1); t2.start(); LOGGER.info("Invoking join"); t2.join(); LOGGER.info("Returned from join"); assertFalse(t2.isAlive()); } 

Kita harus mengharapkan hasil yang serupa dengan yang berikut saat menjalankan kode:

INFO: Thread Created INFO: Invoking join INFO: Thread Thread-1 started INFO: Thread Thread-1 exiting INFO: Returned from join

Metode join () juga dapat kembali jika utas yang direferensikan terputus . Dalam kasus ini, metode akan melontarkan InterruptedException .

Terakhir, jika utas yang direferensikan sudah dihentikan atau belum dimulai, metode panggilan untuk join () segera kembali .

Thread t1 = new SampleThread(0); t1.join(); //returns immediately

3. Metode Thread.join () dengan Timeout

Metode join () akan terus menunggu jika utas yang direferensikan diblokir atau memakan waktu terlalu lama untuk diproses. Ini bisa menjadi masalah karena utas panggilan akan menjadi tidak responsif. Untuk menangani situasi ini, kami menggunakan versi overload dari metode join () yang memungkinkan kami menentukan periode waktu tunggu.

Ada dua versi berjangka waktu yang membebani metode join () :

“Public final void join ( mili panjang ) melempar InterruptedException

Menunggu paling lama milidetik hingga utas ini mati. Waktu tunggu 0 berarti menunggu selamanya. "

“Public final void join (long millis, intnanos ) melempar InterruptedException

Menunggu paling millis milidetik ditambah nano nanodetik untuk thread ini untuk mati.”

Kita dapat menggunakan join berjangka waktu () seperti di bawah ini:

@Test public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout() throws InterruptedException { Thread t3 = new SampleThread(10); t3.start(); t3.join(1000); assertTrue(t3.isAlive()); } 

Dalam hal ini, utas pemanggil menunggu kira-kira 1 detik sampai utas t3 selesai. Jika utas t3 tidak selesai dalam periode waktu ini, metode join () mengembalikan kontrol ke metode panggilan.

Gabungan waktu () bergantung pada OS untuk pengaturan waktu. Jadi, kita tidak bisa berasumsi bahwa join () akan menunggu persis selama yang ditentukan.

4. Metode dan Sinkronisasi Thread.join ()

Selain menunggu hingga penghentian, memanggil metode join () memiliki efek sinkronisasi. join () membuat hubungan terjadi-sebelum:

"Semua tindakan di utas terjadi-sebelum utas lain berhasil kembali dari join () di utas itu.”

Ini berarti bahwa ketika utas t1 memanggil t2.join (), semua perubahan yang dilakukan oleh t2 terlihat di t1 saat kembali. Namun, jika kami tidak memanggil join () atau menggunakan mekanisme sinkronisasi lain, kami tidak memiliki jaminan bahwa perubahan di utas lain akan terlihat oleh utas saat ini meskipun utas lain telah selesai.

Oleh karena itu, meskipun panggilan metode join () ke utas dalam keadaan dihentikan segera kembali, kita masih perlu memanggilnya dalam beberapa situasi.

Kita dapat melihat contoh kode yang tidak disinkronkan dengan benar di bawah ini:

SampleThread t4 = new SampleThread(10); t4.start(); // not guaranteed to stop even if t4 finishes. do { } while (t4.processingCount > 0);

Untuk mensinkronisasi kode di atas dengan benar, kita dapat menambahkan timed t4.join () di dalam loop atau menggunakan mekanisme sinkronisasi lainnya.

5. Kesimpulan

join () metode cukup berguna untuk sinkronisasi antar-utas. Pada artikel ini, kita membahas metode join () dan perilakunya. Kami juga meninjau kode menggunakan metode join () .

Seperti biasa, kode sumber lengkap dapat ditemukan di GitHub.