Tahap pengetahuan yang diperlukan untuk memahami artikel: anda telah menyelesaikan pencarian Java Syntax dan Java Core, dan kini sedang dalam proses mempelajari Java Multithreading. Kebuntuan atau kebuntuan dalam Java atau kebuntuan ialah ralat yang berlaku apabila benang mempunyai pergantungan kitaran pada sepasang objek yang disegerakkan. Bayangkan bahawa satu benang masuk ke monitor objek
Dalam kes ini, kedua-dua benang disekat dan masing-masing sedang menunggu satu sama lain untuk melepaskan kunci. Tetapi tiada seorang pun daripada mereka akan melakukan ini, kerana untuk melakukan ini mereka perlu melengkapkan kaedah mereka, dan ia disekat oleh benang lain. Jadi mereka terperangkap di mana ia berlaku
x
, dan satu lagi masuk ke monitor objek y
. Jika benang dalam objek x
cuba memanggil mana-mana kaedah disegerakkan pada objek y
, dan objek y
pada masa yang sama cuba memanggil mana-mana kaedah disegerakkan pada objek x
, utas akan tersekat menunggu. Di bawah ialah contoh daripada tutorial java docs tentang konsep seperti kebuntuan. Di manakah penyekatan benang berlaku di sini?
public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s" + " has bowed to me!%n", this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s"
+ " has bowed back to me!%n",
this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alphonse =
new Friend("Alphonse");
final Friend gaston =
new Friend("Gaston");
new Thread(new Runnable() {
@Override
public void run() {
// System.out.println("Thread 1");
alphonse.bow(gaston);
// System.out.println("Th: gaston bowed to alphonse");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// System.out.println("Thread 2");
gaston.bow(alphonse);
// System.out.println("2.gaston waiting alph bowed");
}
}).start();
}
}
Terdapat dua perkara penting untuk difahami di sini:
- Apakah sebenarnya yang dilakukan oleh setiap utas yang dijalankan secara serentak?
- Apakah kunci yang digunakan?
Friend
: alphonse
dan gaston
. Setiap daripada mereka mempunyai kunci sendiri. Oleh itu, terdapat dua kunci ini: gigolos dan gastons. Apabila kaedah disegerakkan objek dimasukkan, kuncinya dikunci, dan apabila kaedah itu keluar, ia dilepaskan (atau dibuka kunci). Sekarang mengenai benang. Mari kita panggil benang pertama Alphonse
(dengan huruf besar untuk membezakannya daripada objek alphonse). Inilah yang dilakukannya (sebutkan A
, singkatan untuk Alphonse
):
A: alphonse.bow(gaston) — получает лок alphonse;
A: gaston.bowBack(alphonse) — получает лок gaston;
A: возвращается из обоих методов, тем самым освобождая лок.
Dan inilah yang dilakukan oleh benang pada masa ini Gaston
:
G: gaston.bow(alphonse) — получает лок gaston;
G: alphonse.bowBack(gaston) — получает лок alphonse;
G: возвращается из обоих методов, тем самым освобождая лок.
Sekarang mari kita kumpulkan data ini dan dapatkan jawapannya. Benang boleh dijalin (iaitu, peristiwa mereka akan berlaku) dalam susunan yang berbeza. Kebuntuan akan berfungsi, sebagai contoh, jika susunannya adalah seperti berikut:
A: alphonse.bow(gaston) — получает лок alphonse
G: gaston.bow(alphonse) — получает лок gaston
G: пытается вызвать alphonse.bowBack(gaston), но блокируется, ожидая лока alphonse
A: пытается вызвать gaston.bowBack(alphonse), но блокируется, ожидая лока gaston
deadlock
. Walau bagaimanapun, tenunan lain juga mungkin, di mana salah satu benang akan mempunyai masa untuk disiapkan sebelum yang kedua bermula:
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
Dalam kes ini, tiada sekatan bersama benang. Sebagai contoh, beberapa kaedah telah ditambah yang membolehkan thread lain mempunyai masa untuk dilaksanakan. Apabila hasilnya bergantung pada susunan acara yang berlaku serentak (perintah yang dirancang atau kelajuan pelaksanaan), proses sedemikian dipanggil keadaan perlumbaan dalam bahasa Rusia - "keadaan perlumbaan". Tidak semua keadaan perlumbaan berpotensi menyebabkan kebuntuan, namun, pada pengalaman saya, hanya keadaan perlumbaan yang menyebabkan kebuntuan. Dijawab oleh: Dave Lillethun
Apa lagi yang perlu dibaca: |
---|
Kumpulan Pembangun Java: Pengoptimuman SQL hebat yang tidak bergantung pada model kos. Bahagian 1 |
GO TO FULL VERSION