Макаланы түшүнүү үчүн талап кылынган бorм деңгээли: сиз Java Syntax жана Java Core тапшырмаларын аткардыңыз жана азыр Java Multithreadingди үйрөнүү процессиндесиз. Жавадагы туюк же туюк же туюк - бул жиптер синхрондоштурулган an objectтердин жуптарына циклдик көз карандылыкка ээ болгондо пайда болгон ката. Элестеткиле, бир жип an objectинин мониторуна
Бул учурда, эки жип те бөгөттөлүп, ар бири экинчиси кулпусун бошотууну күтүп турат. Бирок алардын эч кимиси муну жасаbyte, анткени бул үчүн алар өз ыкмасын бүтүрүшү керек жана ал башка жип менен бөгөттөлгөн. Ошентип алар окуя болгон жерде тыгылып калышты
x
, ал эми экинчиси an objectинин мониторуна кирет y
. Эгерде an objectтеги жип x
an objectтеги ар кандай синхрондоштурулган ыкманы чакырууга аракет кылса y
, жана an object y
ошол эле учурда an objectте кандайдыр бир синхрондоштурулган ыкманы чакырууга аракет кылса x
, жиптер күтүүдө тыгылып калат. Төмөндө туюк сыяктуу түшүнүк жөнүндө 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();
}
}
Бул жерде түшүнүү үчүн эки маанилүү нерсе бар:
- Бир убакта иштеп жаткан жиптердин ар бири так эмне кылат?
- Кандай кулпулар колдонулат?
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
. Бирок, башка өрүм да мүмкүн, анда жиптердин бири экинчиси башталганга чейин бүтүрүүгө үлгүрөт:
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
Дагы эмнени окуу керек: |
---|
Java Developer Group: Наркы моделине көз каранды эмес Cool SQL оптималдаштыруу. 1-бөлүк |
GO TO FULL VERSION