JavaRush /Blog Java /Random-MS /Apakah Deadlock di Jawa?
Alexey Smirnov
Tahap
Москва

Apakah Deadlock di Jawa?

Diterbitkan dalam kumpulan
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 x, dan satu lagi masuk ke monitor objek y. Jika benang dalam objek xcuba memanggil mana-mana kaedah disegerakkan pada objek y, dan objek ypada masa yang sama cuba memanggil mana-mana kaedah disegerakkan pada objek x, utas akan tersekat menunggu. Apakah Deadlock?  - 1Di 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:
  1. Apakah sebenarnya yang dilakukan oleh setiap utas yang dijalankan secara serentak?
  2. Apakah kunci yang digunakan?
Mari kita mulakan dari akhir. Katakan anda mencipta dua objek kelas Friend: alphonsedan 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
Apakah Deadlock?  - 2
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 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
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION