Avatar billede bearhugx Nybegynder
23. august 2002 - 00:50 Der 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 :

---------------------
ExpNOTEServer.java

  public synchronized void shutdown() {
    Logger.log(this, "Shutdown commenced...");
    expListener.shutdown();
    Logger.log(this, "Shutdown complete...");
  }
---------------------

og
---------------------
  EkspertenListener.java

  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...

/Søren Munk Skrøder
Avatar billede dsj Nybegynder
23. august 2002 - 14:28 #1
Det er faktisk ganske enkelt at klare, heldigvis for det!
I ExpNOTEServer.java skal det hedde du:

//--------------------------------------\\
volatile boolean notFinished = true;

public synchronized void shutdown() {
  Logger.log(this, "Shutdown commenced...");
  expListener.shutdown();
  while(notFinished) {
    try {
      wait();
    } catch (Exception e) {}
  }
  Logger.log(this, "Shutdown complete...");
}

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!!
Avatar billede dsj Nybegynder
23. august 2002 - 14:30 #2
Der skulle selvfølgelig have stået:

public synchronized void complete() {

:)
Avatar billede bearhugx Nybegynder
23. august 2002 - 14:36 #3
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 :-)

/Søren Munk Skrøder
Avatar billede bearhugx Nybegynder
23. august 2002 - 14:37 #4
SHIT ! -- Jeg kom til at trykke Acceptér !!!
Avatar billede bearhugx Nybegynder
23. august 2002 - 14:37 #5
Sådan går det, når man prøver at gøre det hurtigt og via tabs istedet for mus !
Avatar billede dsj Nybegynder
23. august 2002 - 14:40 #6
Hvad er problemet da. Hvis ikke du kan få det til at virke så vis mig din nye kode.

Og hvis du har flere tråd-problemer eller lignende spørger du bare...
Avatar billede bearhugx Nybegynder
23. august 2002 - 14:42 #7
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();
        }
Avatar billede bearhugx Nybegynder
23. august 2002 - 14:53 #8
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 :-)
Avatar billede bearhugx Nybegynder
23. august 2002 - 14:55 #9
Hvis du ikke kender til expNOTE projektet, så læs http://www.exp.dk/spm/229457
Avatar billede dsj Nybegynder
23. august 2002 - 14:57 #10
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.

Er det forklaring nok?
Avatar billede bearhugx Nybegynder
23. august 2002 - 15:01 #11
dvs. at EkspertenListener i slutningen af sin run()-metode skal kalde ExpNOTEServer.complete ????
Avatar billede bearhugx Nybegynder
23. august 2002 - 15:03 #12
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...
Avatar billede dsj Nybegynder
23. august 2002 - 15:09 #13
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 :)
Avatar billede bearhugx Nybegynder
23. august 2002 - 15:11 #14
send en e-mail til soeren@skroeder.dk - så får du lige et zip-arkiv tilbage :-)
Avatar billede bearhugx Nybegynder
23. august 2002 - 15:26 #15
sendt...
Avatar billede dsj Nybegynder
23. august 2002 - 15:45 #16
modtaget..
kigger lige på det, når jeg har læst http://www.eksperten.dk/spm/229457 færdig (gyyyys)
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester