Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

problem z synchronizacja watkow

0 views
Skip to first unread message

tepesco

unread,
Dec 30, 2005, 6:29:17 AM12/30/05
to
Witam...

Pisze program ktory ma za zadanie polaczyc sie z odpowiednia liczba serverow
ftp i w momencie gdy sie polaczy ze wszystkimi wyslac w tym samym czasie
jedno polecenie...
robie to tak:

tworze watek a w nim wywoluje kolejno do 20watkow laczacych sie z serverami
ftp..

potem w tym watku w metodzie run mam taki kod mniej wiecej:

boolean doit=true;
while (doit){
boolean done=true;
boolean error=false;
for (int i=0;i<20;i++){
if (loginProgress.progress[i]==1)
done=false;
if (loginProgress.progress[i]==-1)
error=true;
}
if (done==true && error==false){
synchronized (ftpSyf){
ftp.notifyAll();
doit=false;
}
}
try{
sleep(100);
}
catch (Exception z){
}
}
}

gdzie progress to tablica postepu ktora sprawdza czy juz jest polaczone
wszystko... to dziala ok..

w klasie ftp w metodzie run mam kod ktory sie laczy z servkiem ftp a potem:

synchronized (this) {
try {
connection = new
conn(whichSite,SiteStuff.Sites[whichSite].activ_bnc,false,true,false);
yield();
wait();
}
catch (InterruptedException e) {
}
}
connection.doCmd(cmd);
yield();
}

gdzie doCmd to metoda ktora wysyla odpowiednia komende do wykonania przez
servek ftp..

moj problem to to ze komenda wysylana jest tylko do pierwszego servera ktroy
sie polaczy... do zadnego innego ;/

za pomoc z gory dziekuje i pozdrawiam


Zbyszek Malec

unread,
Dec 30, 2005, 2:11:10 PM12/30/05
to
tepesco wrote (tak! stara dobra wrotka!):

> Witam...
>
> Pisze program ktory ma za zadanie polaczyc sie z odpowiednia liczba serverow
> ftp i w momencie gdy sie polaczy ze wszystkimi wyslac w tym samym czasie
> jedno polecenie...

To jest dość jasno sformułowane.

> robie to tak:

A tu dalej już nie bardzo.

> tworze watek a w nim wywoluje kolejno do 20watkow laczacych sie z serverami
> ftp..
>
> potem w tym watku w metodzie run mam taki kod mniej wiecej:
>
> boolean doit=true;
> while (doit){
> boolean done=true;
> boolean error=false;
> for (int i=0;i<20;i++){
> if (loginProgress.progress[i]==1)
> done=false;
> if (loginProgress.progress[i]==-1)
> error=true;
> }
> if (done==true && error==false){
> synchronized (ftpSyf){
> ftp.notifyAll();
> doit=false;
> }
> }
> try{
> sleep(100);
> }
> catch (Exception z){
> }
> }
> }

To jest kod czekający aż uda się połączyć z serwerami?
Jakieś dziwne kombinacje tutaj czynisz. Ja bym wywalił aktywne oczekiwanie
(join nie byłby lepszy? albo chociaż jakieś listenery).

> w klasie ftp w metodzie run mam kod ktory sie laczy z servkiem ftp a potem:
>
> synchronized (this) {
> try {
> connection = new
> conn(whichSite,SiteStuff.Sites[whichSite].activ_bnc,false,true,false);
> yield();
> wait();
> }
> catch (InterruptedException e) {
> }
> }
> connection.doCmd(cmd);
> yield();
> }

A co ten kod ma robić? Nie widać żebyś tu jakiejś pętli używał, tak więc
nic dziwnego że kod wykonuje się raz.
Druga rzecz, to straszne pomieszanie konwencji nazewnictwa. Na twoim
miejscu przyjąłbym jedną, proponowaną przez Suna - twoje programy będą dużo
czytelniejsze. Teraz masz Sites (powinno być sites), active_bnc zamiast
activeBnc.


--
Zbigniew Malec Ustronie:104 gg:2756100

Krzysiek

unread,
Dec 30, 2005, 3:36:41 PM12/30/05
to
tepesco napisał(a):

> moj problem to to ze komenda wysylana jest tylko do pierwszego servera ktroy
> sie polaczy... do zadnego innego ;/
>

Metoda notifyAll() budzi wszystkie oczekujące wątki, a one rywalizują
pomiędzy sobą, jeden z nich wygrywa i przejmuje kontrolę, przegrani
muszą dalej czekać.

tepesco

unread,
Dec 30, 2005, 3:45:02 PM12/30/05
to

> Metoda notifyAll() budzi wszystkie oczekujące wątki, a one rywalizują
> pomiędzy sobą, jeden z nich wygrywa i przejmuje kontrolę, przegrani muszą
> dalej czekać.

to jak najprosciej zapewnic sobie zeby wszystkie watki wykonaly sie
jednoczesnie?
a jak nie jednoczesnie to przynajmniej zeby bylo to jakos mniej wiecej w tym
samym czasie

pozdrawiam


tepesco

unread,
Dec 30, 2005, 3:49:33 PM12/30/05
to
>> potem w tym watku w metodzie run mam taki kod mniej wiecej:
>>
>> boolean doit=true;
>> while (doit){
>> boolean done=true;
>> boolean error=false;
>> for (int i=0;i<20;i++){
>> if (loginProgress.progress[i]==1)
>> done=false;
>> if (loginProgress.progress[i]==-1)
>> error=true;
>> }
>> if (done==true && error==false){
>> synchronized (ftpSyf){
>> ftp.notifyAll();
>> doit=false;
>> }
>> }
>> try{
>> sleep(100);
>> }
>> catch (Exception z){
>> }
>> }
>> }
>
> To jest kod czekający aż uda się połączyć z serwerami?
> Jakieś dziwne kombinacje tutaj czynisz. Ja bym wywalił aktywne oczekiwanie
> (join nie byłby lepszy? albo chociaż jakieś listenery).
>
tak, wiem ze mozna to zrobic lepiej ale poki co dziala i mi wystarcza ;)
pozniej to przepisze jakos lepiej...

>> w klasie ftp w metodzie run mam kod ktory sie laczy z servkiem ftp a
>> potem:
>>
>> synchronized (this) {
>> try {
>> connection = new
>> conn(whichSite,SiteStuff.Sites[whichSite].activ_bnc,false,true,false);
>> yield();
>> wait();
>> }
>> catch (InterruptedException e) {
>> }
>> }
>> connection.doCmd(cmd);
>> yield();
>> }
>
> A co ten kod ma robić? Nie widać żebyś tu jakiejś pętli używał, tak więc
> nic dziwnego że kod wykonuje się raz.
> Druga rzecz, to straszne pomieszanie konwencji nazewnictwa. Na twoim
> miejscu przyjąłbym jedną, proponowaną przez Suna - twoje programy będą
> dużo
> czytelniejsze. Teraz masz Sites (powinno być sites), active_bnc zamiast
> activeBnc.

ale to kod klasy dziedziczacej po thread.. wiec trudno zeby tam jakas petla
byla... ma sie wykonac i wylaczyc...

pozdrawiam


Krzysiek

unread,
Dec 30, 2005, 4:34:08 PM12/30/05
to
tepesco napisał(a):
Spróbuj na końcu dodać notifyAll()

synchronized (this) {
try {
connection = new
conn(whichSite,SiteStuff.Sites[whichSite].activ_bnc,false,true,false);
yield();
wait();
}
catch (InterruptedException e) {
}
}
connection.doCmd(cmd);
yield();

notifyAll();
}

tepesco

unread,
Dec 30, 2005, 4:47:55 PM12/30/05
to

>>>Metoda notifyAll() budzi wszystkie oczekujące wątki, a one rywalizują
>>>pomiędzy sobą, jeden z nich wygrywa i przejmuje kontrolę, przegrani muszą
>>>dalej czekać.

dzieki za rade ale nie moze tak byc

java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.notifyAll(Native Method)
at pre1.ftp.run(ftp.java:125)

;)

pozdrawiam


Krzysiek

unread,
Dec 30, 2005, 5:53:48 PM12/30/05
to
tepesco napisał(a):
Hehe :)

Nie wiem jak to masz dokładnie zrobione, więc przygotowałem mały przykład.

Wpierw klasa wątku:

public class TestThread extends Thread {

private int id;

private boolean run = false;

public TestThread(int id) {
super();
this.id = id;
}

public void run() {
System.out.println("Watek "+id+" wystartowal");
doSomething();
System.out.println("Watek "+id+" zakonczyl sie");
}

protected synchronized void doSomething() {
try {
// czekaj na ustawienie flagi
while(!run) {
wait(100);
}
// tu cos robi
// ...
// gotowe, powiadom o tym inne oczekujace watki
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public void setRun(boolean run) {
this.run = run;
}

}

oraz klasa glowna

public class Main {

public static void main(String[] args) {

// Przygotuj watki
TestThread[] threads = new TestThread[10];
for(int i=0;i<10;i++) {
threads[i] = new TestThread(i);
threads[i].start();
}

// Poczekaj 2 sekundy
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

// startuj
for(int i=0;i<10;i++) {
threads[i].setRun(true);
}
}

}

mam nadzieje, ze komentarze wystarcza za opis.

Pozdrawiam,
Krzysztof Białek

tepesco

unread,
Dec 31, 2005, 3:46:42 AM12/31/05
to
Dziekuje za pomoc wszystkim, wystarczylo zrobic tablice watkow i odpowiednio
wywolac notify dla kazdego... jakos nie wiem skad mi sie ubzduralo ze jak
dam notify na jednym to wszystkie zostana powiadomione...

pozdrawiam


0 new messages