JavaRush /Java blogi /Random-UZ /Java-da Deadlock nima?
Alexey Smirnov
Daraja
Москва

Java-da Deadlock nima?

Guruhda nashr etilgan
Maqolani tushunish uchun talab qilinadigan bilim darajasi: siz Java Sintaksisi va Java Core topshiriqlarini bajardingiz va hozir Java Multithreading-ni o'rganish jarayonidasiz. Java-da blokirovka yoki boshi berk ko'chada blokirovka yoki blokirovka - bu ish zarralari sinxronlashtirilgan ob'ektlar juftligiga tsiklik bog'liqlikka ega bo'lganda yuzaga keladigan xato. Tasavvur qiling-a, bir ip ob'ekt monitoriga x, ikkinchisi esa ob'ekt monitoriga kiradi y. Agar ob'ektdagi ip xob'ektdagi har qanday sinxronlashtirilgan usulni chaqirishga harakat qilsa yva ob'ekt ybir vaqtning o'zida ob'ektda har qanday sinxronlashtirilgan usulni chaqirishga harakat qilsa x, iplar kutishda tiqilib qoladi. Deadlock nima?  - 1Quyida java docs o'quv qo'llanmasidan boshi berk ko'rinish kabi tushunchaga misol keltirilgan. Bu erda ip blokirovkasi qayerda sodir bo'ladi?
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();
    }
}
Bu erda ikkita muhim narsani tushunish kerak:
  1. Bir vaqtning o'zida ishlaydigan iplarning har biri aniq nima qiladi?
  2. Qanday qulflar ishlatiladi?
Keling, oxiridan boshlaylik. Aytaylik, siz sinfning ikkita ob'ektini yaratdingiz Friend: alphonseva gaston. Ularning har biri o'z qulfiga ega. Shunday qilib, bu qulflarning ikkitasi bor: gigolos va gastons. Ob'ektning sinxronlashtirilgan usuli kiritilganda, uning blokirovkasi qulflanadi va usuldan chiqqanda u chiqariladi (yoki qulfdan chiqariladi). Endi iplar haqida. Keling, birinchi ipni chaqiramiz Alphonse(uni alfonse ob'ektidan ajratish uchun bosh harf bilan). Bu nima qiladi (keling, uni A, qisqartmasi deb ataylik Alphonse):
A: alphonse.bow(gaston) — получает лок alphonse;
A: gaston.bowBack(alphonse) — получает лок gaston;
A: возвращается из обоих методов, тем самым освобождая лок.
Va bu vaqtda ip nima qilmoqda Gaston:
G: gaston.bow(alphonse) — получает лок gaston;
G: alphonse.bowBack(gaston) — получает лок alphonse;
G: возвращается из обоих методов, тем самым освобождая лок.
Keling, ushbu ma'lumotlarni bir joyga to'playmiz va javobni olamiz. Iplar bir-biriga bog'langan bo'lishi mumkin (ya'ni, ularning hodisalari sodir bo'ladi) turli tartibda. Masalan, agar buyurtma quyidagicha bo'lsa, o'lik ishlaydi:
A: alphonse.bow(gaston) — получает лок alphonse
G: gaston.bow(alphonse) — получает лок gaston
G: пытается вызвать alphonse.bowBack(gaston), но блокируется, ожидая лока alphonse
A: пытается вызвать gaston.bowBack(alphonse), но блокируется, ожидая лока gaston
Deadlock nima?  - 2
Bunday holda, ikkala ip ham bloklanadi va har biri boshqa qulfni bo'shatishini kutadi. Ammo ularning hech biri buni qilmaydi, chunki buning uchun ular o'z usullarini to'ldirishlari kerak va u boshqa ip tomonidan bloklangan. Shunday qilib, ular sodir bo'lgan joyda tiqilib qolishdi deadlock. Shu bilan birga, boshqa to'quv ham mumkin, unda iplardan biri ikkinchisi boshlanishidan oldin tugatish uchun vaqt topadi:
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
Bunday holda, iplarning o'zaro blokirovkasi yo'q. Misol uchun, ba'zi bir usul qo'shildi, bu boshqa ish zarrachasini bajarishga vaqt ajratish imkonini beradi. Natija bir vaqtning o'zida sodir bo'ladigan voqealar tartibiga bog'liq bo'lsa (rejalashtirilgan tartib yoki bajarilish tezligi), bunday jarayon rus tilida poyga sharti - "poyga holati" deb ataladi. Barcha poyga sharoitlari potentsial ravishda boshi berk ko'chaga olib kelmaydi, biroq mening tajribamga ko'ra, faqat poyga sharoitlari o'liklarni keltirib chiqaradi. Muallif: Deyv Lillethun
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION