23. juli 2001 - 22:39Der er
7 kommentarer og 5 løsninger
Thread.stop()
Hejsa! Jeg vil gerne vide, hvad der sker, når man bruger stop()-metoden på en tråd i JAVA. Så vidt jeg har forstået kastes der en DeathException, som man ikke behøver at gribe... Det jeg egentlig gerne vil være sikker på er, at garbage collectoren frigør hukommelsen, som tråden har brugt! Er det korrekt??? Jeg er obs på at stop-metoden er deprecated... men jeg kan ikke se andre muligheder i min situation.
Situation er som følger: Jeg opretter en tråd, som skal lave noget net-kommunikation og returnere resultatet på en plads i et array. Hvis der sker det, at netkommunikation timer ud, så skal tråd stoppes og destrueres. Er der evt. nogen som har løst denne problemstilling før?
Som jeg forstår det, så laver du i tråden en socket op i mod en server.
Den måde jeg ville lave det er, at på den socket du laver, vil jeg lavet et timeout socket.setSoTimeout(<passende interval>); Dette vil så smide en InterruptedException når den timer ud. Denne fanger du i din run metode, og afslutter run, så vil tråden stoppe.
Hvis du ikke har nogen referencer til tråden nogen steder, så vil den blive fjernet af garbage collectoren på et eller andet tidspunkt( dette har man ingen control over )
Tak for det hurtige svar. Jeg må lige tilføje en enkelt ting mere: I tråden laver jeg IKKE en socket. Jeg bruger SOAP, og der er ingen funktionalitet til at sætte en timeout. Derfor bliver jeg nødt til at køre en while-løkke, som fx hvert sekund kigger efter om tråden har placeret noget i resultat-arrayet.
UPS! Måske har jeg ikke været hel god til at formulere min problemstilling. Jeg starter nemlig en række tråde simultant op, og de står og arbejder indtil de timer ud, eller indtil den sidste tråd har afleveret et svar til mit resultat-array.
Men når alt kommer til alt, så skal jeg bare være 110% sikker på at stop()-metoden slår tråden HELT ihjel, da jeg ellers på kort tid vil have flere 100 tråde kørende... jeg har en løsning som fungere efter dette princip, men igen så skal jeg bare være helt sikker. For selv om jeg ikke har nogen reference til tråden, så ligger det jo netop i sagens natur, at tråden fortsætter indtil den stoppes! Altså metoden stop(): Stopper og drøber den tråden definitivt?
metoden stop på en tråd, stopper trådkontrollen, og terminerer trådafviklingen. De referencer, der efterfølgende ikke har nogle objekter kan garbage collectes. Tråden selv er stadig i live, sålænge du har en reference til den, så t.stop(); t = null;
er en god ting i den forbindelse.
Hvis dit socket objekt var erklæret inde i en lokal metode, vil dit socket objekt formodentlig kunne garbage collectes. Hvis det er erklæret inde i et objekt, skal det formodentlig nulstilles.
Sockets er ikke særlig gode i Java, idet de indtil version 1.4 ikke kan interruptes. Hvis man sætter sin Socket til null, vil ens socket objekt blive garbage collected, men det er ikke sikkert at det også gælder de låste system resourcer. Dette afhænger helt af den underliggende VM, særligt om den sætter Socket i TIME_WAIT eller CLOSE.
lbhansen >> Socket.SoTimeout(int) er en 1.3 feature
Du skal/må ikke bruge Thread.stop() - Den er for \"farlig\". Du har ikke noget problem, da tråden automatisk \"dør/smides væk\", når den forlader sin run()-metode. Dette er såfremt du følger de nye retningslinjer for brugen af tråde.
disky>> Memory leaks?? på grund af Thread.stop() :-) Jeg tror du har læst forkert et sted.
Ved Thread.stop() standses trådens eksekvering og alle eventuelle locks i forbindelse med synkronisering og waiting bliver frigivet. Dette betyder, at et synkroniseret objekt kan bremses midt i en synkroniseret metode, som f.eks. fra en firkant:
Her normalt skal extend metoden være atomisk for at ikke have en forkert tilstand, derfor synkroniseret.
Hvis stop bliver kaldt under evt. opdatering, kan det ske at første linie er blevet udført, men ikke den anden, tråden stoppes og objektet firkant er i en forkert tilstand.
suspend() og resume() er samme sag, idet et objekt kan holde en lås på et andet objekt, når det bliver suspenderet, og ingen anden kan derfor opnå låsen.
Grunden til disse tre metoder er blevet deprecated er, at man troede folk godt kunne finde ud af at holde tungen lige i munden, men man tog fejl, og for at \"hjælpe\" folk til at lave bedre kode, valgte man altså at deprecate disse metoder.
Du bliver lige nødt til at lave en skelnen mellem et simultan eksekvering (i eksekveringstråde) og klassen Thread, fordi klassen Thread er en klasse som styrer en tråd, og derfor nærmest en ThreadControl klasse.
At lave et objekt at typen Thread er helt normalt, også selv om den ikke bliver startet. Du kan interagere med den som du har lyst. ala:
Thread t = new Thread(); System.out.println(t.getName()); t.setPriority(t.getPriority()+1); t = null;
I det øjeblik du kalder start() oprettes en ny eksekveringstråd, og den eksekveringstråd har som startpunkt metoden run(). Når metoden run() er overstået, vil denne eksekveringstråd blive afsluttet, og en række flag i objektet af klassen Thread blive opdateret, så f.eks. metoden isAlive() returnerer false.
Metoden isAlive() er sand, imellem dit kald til start() og til run() metoden er færdig, så det giver dig et billede på om du har en tråd (altså en eksekveringstråd) kørende.
stop() var den gamle nødbremse på klassen Thread, som præmaturt terminerede eksekveringstråden (ligesom når run() afsluttes), men på det tidspunkt den nu end var nået til (Se evt. kommentaren til disky ovenfor).
stop() kan du være 100% sikker på, at den stopper eksekveringstråden. Dit problem derimod er om socket bliver lukket ordentligt, det er lidt vm afhængigt (ihvertfald indtil j2sdk1.4, som har nogle bedre løsninger). Det er testscenarier med \"netstat\", så burde den være der :-)
mr. gessle>> Det gør de nu (sun JVM), men trådprioriteter under Windows er lidt lad os kalde det in-deterministisk :-)
Synes godt om
Ny brugerNybegynder
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.