JavaRush /Java блогы /Random-KK /Java тіліндегі тығырыққа тірелу дегеніміз не?
Alexey Smirnov
Деңгей
Москва

Java тіліндегі тығырыққа тірелу дегеніміз не?

Топта жарияланған
Мақаланы түсіну үшін қажетті білім деңгейі: сіз Java синтаксисі және Java негізгі тапсырмаларын орындадыңыз және қазір Java Multithreading тілін үйрену процесіндесіз. Java тіліндегі тұйықталу немесе тұйықталу немесе тұйықталу ағындардың синхрондалған нысандар жұбына циклдік тәуелділігі болған кезде пайда болатын қате. Елестетіп көріңізші, бір жіп an object мониторына түседі x, ал екіншісі an object мониторына түседі y. Егер нысандағы ағын xнысандағы кез келген синхрондалған әдісті шақыруға әрекеттенсе yжәне нысан yбір уақытта нысанда кез келген үндестірілген әдісті шақыруға әрекет жасаса 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. Қандай құлыптар қолданылады?
Соңынан бастайық. Сіз класстың екі нысанын жасадыңыз делік Friend: alphonseжәне gaston. Олардың әрқайсысының өз құлпы бар. Осылайша, бұл құлыптардың екеуі бар: гиголо және гастондар. Объектінің синхрондалған әдісі енгізілгенде оның құлпы құлыпталады, ал әдістен шыққанда ол босатылады (немесе құлыптан босатылады). Енді жіптер туралы. Бірінші жіпті шақырайық Alphonse(оны альфонс нысанынан ажырату үшін бас әріппен). 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
Бұл жағдайда екі жіп те бұғатталады және әрқайсысы екіншісінің құлыпты босатуын күтеді. Бірақ олардың ешқайсысы мұны істемейді, өйткені бұл әрекетті орындау үшін олар өз әдісін аяқтау керек және ол басқа ағынмен бұғатталған. Сондықтан олар болған жерде тұрып қалды deadlock. Дегенмен, басқа тоқу да мүмкін, онда жіптердің біреуі екіншісі басталғанға дейін аяқталады:
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
Бұл жағдайда жіптердің өзара блокталуы болмайды. Мысалы, басқа ағынды орындауға уақыт беруге мүмкіндік беретін кейбір әдіс қосылды. Нәтиже бір мезгілде болатын оқиғалардың ретіне байланысты болса (жоспарланған тәртіп немесе орындалу жылдамдығы), мұндай процесс орыс тілінде жарыс шарты деп аталады - «жарыс шарты». Барлық жарыс жағдайлары тығырықтан шығуы мүмкін емес, дегенмен менің тәжірибемде тек жарыс жағдайлары ғана тығырыққа тіреледі. Жауап берген: Дэйв Лиллетун
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION