23. august 2002 - 00:50Der er
15 kommentarer og 1 løsning
THREADS :: vente på at en anden tråd kører færdig
Hejsa --- i forbindelse med expNOTE projektet er jeg kørt lidt fast angående styrringen af trådene:
Jeg har en server, som på et tidspunkt kan modtage en "shutdown"-besked - når dette sker, skal jeg sørge for at en tråd (som varetager en socket-connection) når til slutningen af dens run()-metode...
I tråden har jeg et "isAlive" flag (boolean), som sættes til false, når shutdown-beskeden modtages
Det er måske bedre, hvis jeg lige skriver noget kode :
public synchronized void shutdown() { isActive = false; }
public void run() { try { ServerSocket listeningSocket = new ServerSocket(ExpNOTEServer.serverPort); Logger.log(this, "Socket listener activated..."); while( isActive ) { Socket incomming = listeningSocket.accept(); : : Gør, hvad der skal gøres : incomming.close(); } } catch( Exception ex ) { Logger.log(this, "EXCEPTION : Failed to listen on port "+ExpNOTEServer.serverPort); ex.printStackTrace(); } Logger.log(this, "reached end of run()"); } ---------------------
Nu er sådan, at efter serveren modtager "shutdown" signalet, så kaldes EkspertenListener.shutdown(), som sætter isAlive Falsk... So far - so good...
Men hvordan kan jeg forhindre tråden i ExpNOTEServer.java i at fortsætte indtil efter EkspertenListener.java's run() igen er blevet aktiveret (og den så ser at isAlive er falsk - slutter løkken - lukker socketConnectionen og udskriver "reached end of run()")
Ja - hvordan får jeg hovedtråden til at vente med at eksekvere til EkspertenListener-tråden har nået slutningen af run()-metoden... så jeg får outputtet
[com.eksperten.ExpNOTEServer.ExpNOTEServer] Shutdown commenced... [com.eksperten.ExpNOTEServer.EkspertenListener] reached end of run()... [com.eksperten.ExpNOTEServer.ExpNOTEServer] Shutdown complete...
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
public synchronized complete() { notFinished = false; notifyAll(); } \\--------------------------------------//
I EkspertenListener.java kalder du blot complete(); i slutningen af run(), altså umiddelbart efter Logger.log(this, "reached end of run()");
Så skulle den faktisk være i vinkel. Jeg har dog lige en bemærkning til tråde-programmering: Rigtig mange programmører glemmer at erklære deres variable "volatile". Når du nu kalder metoden shutdown() og sætter en variabel, er det faktisk kun den lokale kopi af variablen der ændres på i første omgang (altså i den klasse der kalder metoden). Faktisk kan du slet ikke være sikker din isActive i EkspertenListener.java ændres med det samme. Hvis du erklærer variable, som skal deles mellem tråde, "volatile" sørger JVM for at alle lokale kopier af den aktuelle variabel opdateres med det samme!!
Jeg tester det lige... -- Jeg har også et andet - thread/connection orienteret problem, som du måske kan være behjælpelig med, men det kommer lige om et stykke tid...
Jeg håber jeg kan bruge din kode - jeg lavede nemlig lidt om i koden efter jeg havde oprettet spørgsmålet i går aftes :-)
hmmm istedet for at lave en complete-metode, kan jeg så i run-metoden gøre følgende ? : Logger.log(this, "reached end of run()"); Logger.log(this, "shutdown complete..."); synchronized(this) { isComplete = true; notifyAll(); }
Jeg skal lige have det igen... Skal wait() og notifyAll() være i samme klasse eller ...
Jeg har prøvet med synchronized(this)-versionen - og den når ikke at "afslutte" programmet...
Er du meget god til tråde ???? ... For hvis du kunne kigge lidt på koden i helhed, så ved jeg at der vil være mange Eksperten-brugere, som vil være glade for din hjælp :-)
Nej. Den måde jeg viste dig er sådan en standardiseret vente-metode (så du ikke tror det er hjemme-opfundet).
Det eneste du opnår er, at kun ét objekt har adgang synchronized(this)-blokken på samme tid. Faktisk vil den slet ikke vente der, men bare løbe igennem som før. Mit forslag er stadig det du skal bruge.
Grunden til at det skal være sådan er, at EkspertenListener.java selv skal gøre opmærksom på, at den er færdig. Det kan den kun gøre ved at kalde en metode på den ventende tråd. Hvis du af en eller anden grund ikke synes om at de skal have direkte adgang til hinanden, kan du lave et objekt de så kan dele. Hvis du vil det, skal jeg nok vise dig, hvordan du gør, men det er efter min mening mere besværligt og har ikke rigtig nogen fordele.
Det der faktisk sker er, at når ExpNOTEServer.java når ned til wait(), vil den gå over block-mode (vente) til der køres en notifyAll() et eller andet sted i dit program. while-løkken udenom er kun til for at sikre, at de rigtige omstændigheder er til stede. Faktisk kunne du undvære while-løkken i dit tilfælde, men det er "dårlig" programmering, men kan lade sig gøre, så længe der INGEN andre steder kaldes notifyAll(). For at være sikker på at intet går galt bør du tage den med.
Vil du evt. se hele koden... Jeg er _MEGET_ interesseret i at få den færdiglavet -- og disse tread/connection-problemer er de eneste irriterende, som er tilbage...
Ja, wait() og notifyAll() skal være i samme klasse. Ja, EkspertenListener skal i slutningen af sin run()-metode kalde ExpNOTEServer.complete(). Ja, jeg er god til tråde. og Ja, jeg vil gerne se hele koden :)
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.