JavaRush /Java блогу /Random-KY /Javaдагы Deadlock деген эмне?
Alexey Smirnov
Деңгээл
Москва

Javaдагы Deadlock деген эмне?

Группада жарыяланган
Макаланы түшүнүү үчүн талап кылынган бorм деңгээли: сиз Java Syntax жана Java Core тапшырмаларын аткардыңыз жана азыр Java Multithreadingди үйрөнүү процессиндесиз. Жавадагы туюк же туюк же туюк - бул жиптер синхрондоштурулган an objectтердин жуптарына циклдик көз карандылыкка ээ болгондо пайда болгон ката. Элестеткиле, бир жип an objectинин мониторуна x, ал эми экинчиси an objectинин мониторуна кирет y. Эгерде an objectтеги жип xan objectтеги ар кандай синхрондоштурулган ыкманы чакырууга аракет кылса y, жана an object yошол эле учурда an objectте кандайдыр бир синхрондоштурулган ыкманы чакырууга аракет кылса x, жиптер күтүүдө тыгылып калат. Deadlock деген эмне?  - 1Төмөндө туюк сыяктуу түшүнүк жөнүндө java docs окуу куралынан мисал келтирилген. Бул жерде жипти бөгөттөө кайда болот?
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();
    }
}
Бул жерде түшүнүү үчүн эки маанилүү нерсе бар:
  1. Бир убакта иштеп жаткан жиптердин ар бири так эмне кылат?
  2. Кандай кулпулар колдонулат?
Келгиле, аягынан баштайлы. Сиз класстын эки an objectисин түздүңүз дейли Friend: alphonseжана gaston. Алардын ар биринин өзүнүн кулпусу бар. Ошентип, бул эки кулпу бар: гиголо жана гастон. Объекттин синхрондуу ыкмасы киргизилгенде анын кулпусу бекитилет, ал эми методдон чыкканда ал бошотулат (же кулпусу ачылат). Эми жиптер жөнүндө. AlphonseБиринчи жипти (алфонс an objectисинен айырмалоо үчүн баш тамга менен) чакыралы . Ал эмне кылат (келгиле, аны деп атайлы A, кыскасы Alphonse):
A: alphonse.bow(gaston) — получает лок alphonse;
A: gaston.bowBack(alphonse) — получает лок gaston;
A: возвращается из обоих методов, тем самым освобождая лок.
Бул жерде жип учурда эмне кылып жатат Gaston:
G: gaston.bow(alphonse) — получает лок gaston;
G: alphonse.bowBack(gaston) — получает лок alphonse;
G: возвращается из обоих методов, тем самым освобождая лок.
Эми бул маалыматтарды чогултуп, жооп алалы. Жиптер ар кандай тартипте чырмалышып (б.а. алардын окуялары болот) болушу мүмкүн. Туюк, мисалы, буйрук төмөнкүдөй болсо, иштейт:
A: alphonse.bow(gaston) — получает лок alphonse
G: gaston.bow(alphonse) — получает лок gaston
G: пытается вызвать alphonse.bowBack(gaston), но блокируется, ожидая лока alphonse
A: пытается вызвать gaston.bowBack(alphonse), но блокируется, ожидая лока gaston
Deadlock деген эмне?  - 2
Бул учурда, эки жип те бөгөттөлүп, ар бири экинчиси кулпусун бошотууну күтүп турат. Бирок алардын эч кимиси муну жасаbyte, анткени бул үчүн алар өз ыкмасын бүтүрүшү керек жана ал башка жип менен бөгөттөлгөн. Ошентип алар окуя болгон жерде тыгылып калышты deadlock. Бирок, башка өрүм да мүмкүн, анда жиптердин бири экинчиси башталганга чейин бүтүрүүгө үлгүрөт:
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
Бул учурда, жиптердин өз ара бөгөт коюу жок. Мисалы, башка жипти аткарууга убакыт бере турган кандайдыр бир ыкма кошулду. Натыйжа бир эле учурда болуп жаткан окуялардын тартибине (пландуу тартип же аткаруунун ылдамдыгына) көз каранды болгондо, мындай процесс орус тorнде жарыш шарты деп аталат - "жарыш шарты". Бардык жарыш шарттары туңгуюкка себеп боло бербейт, бирок менин тажрыйбам боюнча, жарыш шарттары гана туюктарды жаратат. Жазган: Dave Lillethun
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION