threads
10 отговора
364 прегледа
threads
Наскоро разглеждах един пример за прост чат сървър на java, който беше постнат в този форум. В него се използваше notify() за уведомяване на нишки, за които е извикан метода wait(). В една книжка прочетох, че notify уведомява произволна нишка, а май това не е смисъла на програмата.
Имате ли предположение!?
Предварително благодаря:)
Имате ли предположение!?
Предварително благодаря:)
Re: threads
izpolzva se notify() za "proizvona" ni6ka ili notifyAll()(uvedomiava vsi4ki) za izlizane wait().Ne sam 4ela programata, no i vav vaprosa ti ne stava iasno kakvo pita6.
Re: threads
ето малко код и обяснението на пишештия програмата:
/**
* Adds given message to the dispatcher's message queue and notifies this
* thread to wake up the message queue reader (getNextMessageFromQueue method).
* dispatchMessage method is called by other threads (ClientListener) when
* a message is arrived.
*/
public synchronized void dispatchMessage(ClientInfo aClientInfo, String aMessage)
{
Socket socket = aClientInfo.mSocket;
String senderIP = socket.getInetAddress().getHostAddress();
String senderPort = "" + socket.getPort();
aMessage = senderIP + ":" + senderPort + " : " + aMessage;
mMessageQueue.add(aMessage);
notify();
}
ето и частта, която кара тази нишка да чака:
* @return and deletes the next message from the message queue. If there is
* no messages in the queue, falls in sleep until notified by dispatchMessage
* method.
*/
private synchronized String getNextMessageFromQueue()
throws InterruptedException
{
while (mMessageQueue.size()==0)
wait();
String message = (String) mMessageQueue.get(0);
mMessageQueue.removeElementAt(0);
return message;
}
Мисля, че авторът е искал да уведоми конкретно тази нишка. Въпросът е, че в същото време има други заспали нишки. Ето и част от техния код, който е много близък по структура:
* @return and deletes the next message from the message queue. If the queue
* is empty, falls in sleep until notified for message arrival by sendMessage
* method.
*/
private synchronized String getNextMessageFromQueue()
throws InterruptedException
{
while (mMessageQueue.size()==0)
wait();
String message = (String) mMessageQueue.get(0);
mMessageQueue.removeElementAt(0);
return message;
}
и за nofify:
* Adds given message to the message queue and notifies this thread
* (actually getNextMessageFromQueue method) that a message is arrived.
* sendMessage is called by other threads (ServeDispatcher).
*/
public synchronized void sendMessage(String aMessage)
{
mMessageQueue.add(aMessage);
notify();
}
Ей, това е (на кратко:). Ако някой се интересува - ето и целия код в zip
[линк]
/**
* Adds given message to the dispatcher's message queue and notifies this
* thread to wake up the message queue reader (getNextMessageFromQueue method).
* dispatchMessage method is called by other threads (ClientListener) when
* a message is arrived.
*/
public synchronized void dispatchMessage(ClientInfo aClientInfo, String aMessage)
{
Socket socket = aClientInfo.mSocket;
String senderIP = socket.getInetAddress().getHostAddress();
String senderPort = "" + socket.getPort();
aMessage = senderIP + ":" + senderPort + " : " + aMessage;
mMessageQueue.add(aMessage);
notify();
}
ето и частта, която кара тази нишка да чака:
* @return and deletes the next message from the message queue. If there is
* no messages in the queue, falls in sleep until notified by dispatchMessage
* method.
*/
private synchronized String getNextMessageFromQueue()
throws InterruptedException
{
while (mMessageQueue.size()==0)
wait();
String message = (String) mMessageQueue.get(0);
mMessageQueue.removeElementAt(0);
return message;
}
Мисля, че авторът е искал да уведоми конкретно тази нишка. Въпросът е, че в същото време има други заспали нишки. Ето и част от техния код, който е много близък по структура:
* @return and deletes the next message from the message queue. If the queue
* is empty, falls in sleep until notified for message arrival by sendMessage
* method.
*/
private synchronized String getNextMessageFromQueue()
throws InterruptedException
{
while (mMessageQueue.size()==0)
wait();
String message = (String) mMessageQueue.get(0);
mMessageQueue.removeElementAt(0);
return message;
}
и за nofify:
* Adds given message to the message queue and notifies this thread
* (actually getNextMessageFromQueue method) that a message is arrived.
* sendMessage is called by other threads (ServeDispatcher).
*/
public synchronized void sendMessage(String aMessage)
{
mMessageQueue.add(aMessage);
notify();
}
Ей, това е (на кратко:). Ако някой се интересува - ето и целия код в zip
[линк]
Re: threads
Ami tova e taka za6toto ima edin ServerDispacher kojto se griji edinstveno za
polu4avaneto na msg ot daden client i negovoto izpra6tane do ostanalite
i 4ast ot koda e za tova (dispatchMessage i getNextMessageFromQueue), i tuk
stava vupros za edna ni6ka.
Za vseki klient ima otdelna ni6ka ( ClientSender ) koiato izpra6ta msg kum
syotvetniat klient.
Kogato ima msg Dispacher-a izvikva sendMessage() na ClientSender i tova za vseki klient i taka vsu6nost 6te se sybudiat tezi ni6ki.
Ako ti e bil za tova vuprosa?
polu4avaneto na msg ot daden client i negovoto izpra6tane do ostanalite
i 4ast ot koda e za tova (dispatchMessage i getNextMessageFromQueue), i tuk
stava vupros za edna ni6ka.
Za vseki klient ima otdelna ni6ka ( ClientSender ) koiato izpra6ta msg kum
syotvetniat klient.
Kogato ima msg Dispacher-a izvikva sendMessage() na ClientSender i tova za vseki klient i taka vsu6nost 6te se sybudiat tezi ni6ki.
Ako ti e bil za tova vuprosa?
Re: threads
Така е, Калине, ако се извиква последователно случайно някоя заспала sender нишка най-накрая пак всички ще бъдат извикани. Това което не се вързва, според мен поне - нали ако приемем че се свързва само един клиент ще има 2 нишки, които веднага заспиват - client sender & serverdispatcher. Първо явно ще се изпълни метода за нотифициране на serverdispatcher, който според моите познания трябва да събуди една от двете нишки - sender or dispatcher. Може и да се бъркам, разбира се. Може би notify нотифицира само нишки от един и същи тип... Ти кажи:)
Ето, пичове
какво пише точно в документацията:
The choice is arbitrary and occurs at the discretion of the implementation.
Тъй че избор кой да бъде нотифициран не може да направи програмиста. Аз прегледах отгоре-отгоре тоя код, дето го постнахте тука, и не видях да е измислено нещо, с което да се уведомява конкретна нишка.
Ако въпросът е как може да се направи подобно нещо, имам една идейца в стил Ц. Като в доброто старо време, прави се една управляваща променлива с тип незнам какъв, зависи от случая. Тя ще трябва да е статик и публик, пък ако се налага и файнал, макар че тогава малко ще се изгуби смисълът. И всяка нишка която чака, трябва да има някакъв механизъм, който според тая променлива да проверява "аджеба аз ли трябва да върша работа сега, или да взема пак да заспивам до следваща проверка". Само че тогава задължително се използва НотифуАлл. И ако са доста нишките, програмката може да не върви мноу бързо ;P
It`s more fun to compute
The choice is arbitrary and occurs at the discretion of the implementation.
Тъй че избор кой да бъде нотифициран не може да направи програмиста. Аз прегледах отгоре-отгоре тоя код, дето го постнахте тука, и не видях да е измислено нещо, с което да се уведомява конкретна нишка.
Ако въпросът е как може да се направи подобно нещо, имам една идейца в стил Ц. Като в доброто старо време, прави се една управляваща променлива с тип незнам какъв, зависи от случая. Тя ще трябва да е статик и публик, пък ако се налага и файнал, макар че тогава малко ще се изгуби смисълът. И всяка нишка която чака, трябва да има някакъв механизъм, който според тая променлива да проверява "аджеба аз ли трябва да върша работа сега, или да взема пак да заспивам до следваща проверка". Само че тогава задължително се използва НотифуАлл. И ако са доста нишките, програмката може да не върви мноу бързо ;P
It`s more fun to compute
Re: threads
Da,kogato ima6 synchronized na nestati4en metod sinhronizaciata e po teku6tia obekt,(this).
I pri dispachera sinhronizaciata e po nego obekt t.e. notify vyv dispachera NE
sybujda sendera.Toj se sybujda kogato mu se izprati syob6tenie ot dispa4era
t.e. ako imame edin sender i dispa4er kogato se polu4i msg dispa4era se sybujda(
s notify() kojto oba4e zasiaga samo nego)
i toi ot svoia strana pra6ta na sendera tova msg i togava se sybujda
(s negovia notify)
I kogato ima pove4e senderi principa e su6tiat.Pyrvo se sybujda dispa4era i toi budi vsi4ki senderi.
Taka kak e?
I pri dispachera sinhronizaciata e po nego obekt t.e. notify vyv dispachera NE
sybujda sendera.Toj se sybujda kogato mu se izprati syob6tenie ot dispa4era
t.e. ako imame edin sender i dispa4er kogato se polu4i msg dispa4era se sybujda(
s notify() kojto oba4e zasiaga samo nego)
i toi ot svoia strana pra6ta na sendera tova msg i togava se sybujda
(s negovia notify)
I kogato ima pove4e senderi principa e su6tiat.Pyrvo se sybujda dispa4era i toi budi vsi4ki senderi.
Taka kak e?
Re: threads
Мерси, Калине. Само последно доуточнение: не ми стана съвсем ясно какво имаш предвид като казваш, че синхронизацията е по текущия обект (ако правилно цитирам) и какво общо има между т.нар. синхронизация по текущия обект и нотифицирането само на диспачера.
Извинявам се, ако съм досадил, но се опитвам да разбера нещата още отначало, а не да оставам с някави мъгляви представи, че уж зная нещо.
Извинявам се, ако съм досадил, но се опитвам да разбера нещата още отначало, а не да оставам с някави мъгляви представи, че уж зная нещо.
Re: threads
Мисля си дори дали чакащите тредове не са групирани по някакъв начин според своя монитор и да се нотифицират само тези, които принадлежат към дадения мониторл Ама пак ти кажил
Re: threads
Ami ok.
Eto malko obiasnenia (doklokoto 6te uspeia):
public static synchronized void method(Object obj){
//kod
}
Tova ozna4ava 4e 2 ni6ki ne mogat da izpulniavat tozi kod edno-
vremenno.Oba4e ne vinagi ima nujda da se pravi taka.Naprimer ako
v tozi kod ima niakakav obekt koito e "problemen" t.e. iska6 nego
da opazi6 ot mazane moje6 da napravi6 sinchronizaciata po nego:
public static void method(Object obj){
synchronized(obj){
//kod
}}
V tozi slu4ai kodyt 6te se izpulniava su6to samo ot edna ni6ka oba4e moje da se izpulniava ot druga za koiato obj e drug,t.e. se polu4ava sinchronizacia po obekta a ne po metoda.(vsu6nost purviat slu4ai
e su6to sinchronizacia po obekt i tozi obekt e vsy6nost samia klas na koito e metoda).
Smisala e ako ima6 10 ni6ki koito obrabotavat obekta A i edna koiato
iska da pravi ne6to s obekta B,niama smisul tazi poslednata da 4aka ni6kite koito majat A.(pri polojenie 4e tova sa ti "problemnite" obekti).Sy6ta taka za da opazi6 naistina tozi obekt triabva da ima6
takav sinchroniziran blok navsiakade kydeto izpolzva6 obekta ina4e se gubi celia smisul.
Drug slu4ai e kogato ima6
public synchronized void method() {...}
E tova e ve4e sincronizaciata po teku6tia obekt.Tova e su6to kato da napi6e6
public void method() {
synchronized(this){
...
}
}
I nai-nakriaia v mnogo slu4ai e udobno da se izpolzvat
metodite wait() i notify().Te se vikat v sinchronizirana sekcia
wait() blokirva teku6tata ni6ka i otklu4va monitora na obekta po koito e sinchronizaciata.
notify puk sybujda proizvolna ni6ka ot ni6kite 4aqka6ti po obekta i
go zaklu4va.Tozi obekt se otklu4va ili kogato ni6kata izleze ot koda koito e sinchroniziran ili kogato se izvika wait();.
Ima za tova edin klasi4eski primer
za proizvoditelia i konsumatora.Ima edin sklad koito ima niakakav razmer.Rabotata na proizvoditelia e da buta tam stoka(primerno kroasani) a na konsumatora da vadi i da iade:).
Da ama proizvoditelia triaba da spre da proizvejda ako napulni sklada i da 4aka dokato se osvobodi miasto.Su6toto vaji i za konsumatora
toi 6te iade ako ima ne6to v skalda ako e prazen i toi 4aka.
I kogato proizvoditelia sloji v slkada kroasan toi kazva na konsumatorite 4e ima kroasani(No zabeleji na tezi koito 4akat za kroasani na tozi sklad a ne tezi koito 4akat na drug )
A kogato konsumatora vzeme ot sklada,to toi triabva da sybudi proizvoditelia.
Neznam dali go obiasnih razbiraemo.Sega pak razgledai koda na chata
i otkrii koi pravi kroasani kyde sa skladovete i koi za kakvo 4aka:))
Eto malko obiasnenia (doklokoto 6te uspeia):
public static synchronized void method(Object obj){
//kod
}
Tova ozna4ava 4e 2 ni6ki ne mogat da izpulniavat tozi kod edno-
vremenno.Oba4e ne vinagi ima nujda da se pravi taka.Naprimer ako
v tozi kod ima niakakav obekt koito e "problemen" t.e. iska6 nego
da opazi6 ot mazane moje6 da napravi6 sinchronizaciata po nego:
public static void method(Object obj){
synchronized(obj){
//kod
}}
V tozi slu4ai kodyt 6te se izpulniava su6to samo ot edna ni6ka oba4e moje da se izpulniava ot druga za koiato obj e drug,t.e. se polu4ava sinchronizacia po obekta a ne po metoda.(vsu6nost purviat slu4ai
e su6to sinchronizacia po obekt i tozi obekt e vsy6nost samia klas na koito e metoda).
Smisala e ako ima6 10 ni6ki koito obrabotavat obekta A i edna koiato
iska da pravi ne6to s obekta B,niama smisul tazi poslednata da 4aka ni6kite koito majat A.(pri polojenie 4e tova sa ti "problemnite" obekti).Sy6ta taka za da opazi6 naistina tozi obekt triabva da ima6
takav sinchroniziran blok navsiakade kydeto izpolzva6 obekta ina4e se gubi celia smisul.
Drug slu4ai e kogato ima6
public synchronized void method() {...}
E tova e ve4e sincronizaciata po teku6tia obekt.Tova e su6to kato da napi6e6
public void method() {
synchronized(this){
...
}
}
I nai-nakriaia v mnogo slu4ai e udobno da se izpolzvat
metodite wait() i notify().Te se vikat v sinchronizirana sekcia
wait() blokirva teku6tata ni6ka i otklu4va monitora na obekta po koito e sinchronizaciata.
notify puk sybujda proizvolna ni6ka ot ni6kite 4aqka6ti po obekta i
go zaklu4va.Tozi obekt se otklu4va ili kogato ni6kata izleze ot koda koito e sinchroniziran ili kogato se izvika wait();.
Ima za tova edin klasi4eski primer
za proizvoditelia i konsumatora.Ima edin sklad koito ima niakakav razmer.Rabotata na proizvoditelia e da buta tam stoka(primerno kroasani) a na konsumatora da vadi i da iade:).
Da ama proizvoditelia triaba da spre da proizvejda ako napulni sklada i da 4aka dokato se osvobodi miasto.Su6toto vaji i za konsumatora
toi 6te iade ako ima ne6to v skalda ako e prazen i toi 4aka.
I kogato proizvoditelia sloji v slkada kroasan toi kazva na konsumatorite 4e ima kroasani(No zabeleji na tezi koito 4akat za kroasani na tozi sklad a ne tezi koito 4akat na drug )
A kogato konsumatora vzeme ot sklada,to toi triabva da sybudi proizvoditelia.
Neznam dali go obiasnih razbiraemo.Sega pak razgledai koda na chata
i otkrii koi pravi kroasani kyde sa skladovete i koi za kakvo 4aka:))
Re: threads
Калине, мерси за изчерпателния отговор - беше ми невероятно полезен. Всичко става пределно ясно сега и много по-подредено (поне в мойта глава:). Имаш 10Х на 10-та степен от мен.
Хайде чао и лека работа:)
Хайде чао и лека работа:)