Σταμάτημα thread σε Java

Συζητήσεις για γλώσσες προγραμματισμού και θέματα σχετικά με προγραμματισμό.
Post Reply
User avatar
tsilochr
Wow! Terabyte level
Wow! Terabyte level
Posts: 3246
Joined: Tue Mar 16, 2004 2:47 pm
Academic status: PhD
Gender:
Location: mm.aueb.gr
Contact:

Σταμάτημα thread σε Java

Post by tsilochr » Mon Nov 19, 2007 10:17 am

Αυτή το φορά το πρόβλημα είναι το εξής. Έχουμε ένα thread σε java που τρέχει στο παρασκήνιο της εφαρμογής διότι κάνει αρκετή ώρα να ολοκληρώσει τη λειτουργία του. Θέλουμε να μπορούμε να το σταματήσουμε ρητά (πχ με κάποιο κουμπί cancel).

Στην αρχή σκέφτηκα το πιο απλό, δλδ να σκοτώσω το thead με την Thread.stop() αλλά κοιτώντας στο web είδα ότι η εν λόγω μέθοδος θεωρείται depricated και επικίνδυνη. Αντ' αυτού προτείνεται να χρησιμοποιηθεί μια μεταβλητή ως flag την οποία θα ελέγχει το thread. Σε αυτή τη περίπτωση όμως ο κώδικας του Thread θα πρέπει να είναι της μορφής

Code: Select all

while (condition)
{
   doThat(); //...
}
όμως εγώ
1. δεν θέλω το thread να κάνει loopες, μια φορά εκτελεί αυτό που θέλω

Code: Select all

void run()
{
  doThat(); // takes a lot of time
}
2. θέλω να το σταματώ ακαριαία και δεν θέλω σε κάθε δυο γραμμές του thread ένα if(!condition) return;

Έχει αντιμετωπίσει κανείς παρόμοια κατάσταση?
User avatar
P3
Venus Project Founder
Venus Project Founder
Posts: 2722
Joined: Mon Mar 22, 2004 4:12 pm
Academic status: Alumnus/a
Gender:
Location: !! El Paso !!

Post by P3 » Mon Nov 19, 2007 10:49 am

Εγώ είχα φτιάξει μια εφαρμογή που είχε ένα κουμπί "Stop" και έκανε:

Code: Select all

Thread.stop()
ή 
Thread.suspend()
όμως αυτό μπορεί να οδηγήσει σε deadlocks. Μπορείς να βάλεις στο action του κουμπιού να κάνει sleep το thread για όσο θες!
"Το δικό μου το ποίημα δεν έχει ομοιοκαταληξία.", ο υπογράφων
Klefths
bit level
bit level
Posts: 45
Joined: Sat Oct 28, 2006 5:42 pm
Gender:
Location: Αθήνα

Post by Klefths » Mon Nov 19, 2007 1:42 pm

Βασικά προτείνω την Thread.wait() ή Thread.wait(int milliseconds). Αν θυμάμαι καλά αν χρησιμοποιήσεις την sleep δε μπορείς να κάνεις μετά το thread notify. Επίσης με την sleep πρέπει να δηλώσεις πόσο χρόνο πρέπει το thread να μείνει ανενεργό ενώ αν κατάλαβα καλά εσύ θες να το σταματήσεις για πάντα και αν θες το ξυπνάς από μόνος σου αργότερα. Για να το ξυπνήσεις χρησιμοποίησε την Thread.notify().

Η Thread.suspend() και Thread.stop() είναι deprecated και εδώ ο λόγος. Στο link έχει επίσης κάποια παραδείγματαγια το πως μπορείς να τις αντικαταστήσεις.
User avatar
tsilochr
Wow! Terabyte level
Wow! Terabyte level
Posts: 3246
Joined: Tue Mar 16, 2004 2:47 pm
Academic status: PhD
Gender:
Location: mm.aueb.gr
Contact:

Post by tsilochr » Mon Nov 19, 2007 6:00 pm

βασικά έχω δει αυτές τις λύσεις αλλά δεν ταιριάζουνε στο thread μου. Η λειτουργία του κάνει πολύ ώρα να ολοκληρωθέι και εγώ θέλω να το καταστρέψω On demand. Την wait() δεν μπορώ να σκεφτώ πως θα την εκμεταλευτώ. Σχετικά με το flag variablr, αν απλώς βάλω σε κάθε 2 γραμμές έναν έλεγχο για την μεταβλητή ελέγχου τότε θα έχω το εξής πρόβλημα

Code: Select all

...
doSomething(); //εδώ παίρνει πολύ χρόνο
if (!flagVar) return;
Αν η doSomething() κάνει πολύ ώρα δεν μπορώ να την σταματήσω. Εγώ θέλω να κοπεί απότομα.
User avatar
HdkiLLeR
Venus Project Founder
Venus Project Founder
Posts: 4356
Joined: Tue Jan 27, 2004 4:41 pm
Academic status: Alumnus/a
Gender:
Location: New York, NY
Contact:

Post by HdkiLLeR » Mon Nov 19, 2007 7:46 pm

Χρήστο η doSomething() τι κάνει; μέσα έχεις μόνο computational code (δεν νομίζω) η και objects τα οποία πειράζεις;
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d-->--- s+:+ a- C++(+++) BILS++++$ P--- L++++>+++++ E--- W+++ N+ o+ K w--
O M+ V-- PS++>+++ PE- Y++ PGP++ t+ 5+ X+ R* tv b++ DI- D+ G+++ e+++>++++ h r++ y++
------END GEEK CODE BLOCK------

"UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity." -- Dennis Ritchie
User avatar
tsilochr
Wow! Terabyte level
Wow! Terabyte level
Posts: 3246
Joined: Tue Mar 16, 2004 2:47 pm
Academic status: PhD
Gender:
Location: mm.aueb.gr
Contact:

Post by tsilochr » Mon Nov 19, 2007 11:04 pm

η doSomething δεν πειράζει δομές που μοιράζονται τα υπόλοιπα threads, κάνει computational πράγματα, μιλάει μέσω web services αλλά δεν γράφει παρά μόνο διαβάζει και υπολογίζει κάτι μετρικές.

Πάντως ο Tomahawk με βοήθησε μαθαίνοντας μου την ExecutorService
που έχει shutdown!
User avatar
HdkiLLeR
Venus Project Founder
Venus Project Founder
Posts: 4356
Joined: Tue Jan 27, 2004 4:41 pm
Academic status: Alumnus/a
Gender:
Location: New York, NY
Contact:

Post by HdkiLLeR » Tue Nov 20, 2007 1:45 am

Ναι υπάρχούν αυτά τα ωραία καλούδια (του concurrent package) απο την 1.5 και μετά.

Υπάρχει ένα θέμα βέβαια, υπόψην δεν έχω γράψει production code με την ExecutorService ποτέ οπότε δεν είμαι και ιδιαίτερα σίγουρος. Η shutdown() κάνει schedule ένα shutdown του service σου. Συνεπώς δεν σημαίνει ότι το σταματάει επιτόπου. Στα περισσότερα jvms δεν νομίζω ότι κάνει τπτ παραπάνω απο το να περιμένει να τελειώσει η run() και να κάνει dispose το thread.

Γι' αυτό τον λόγο υπάρχει και η shutdownNow() η οποία είναι όμως και αυτή best-effort, δηλαδή άντε να κάνει κανένα interupt() στο thread για να το ξεκολήσει εάν είναι σε blocked state και να γίνει scheduled το shutdown του. Αυτό που θέλεις να κάνεις δεν είναι και ιδιαίτερα εύκολο εάν το αναλογιστείς γιατί θέλεις την στιγμή που τρέχει code μέσα σε μια method να μπορέσεις να μεταφέρεις τον έλεγχο αλλού και μάλιστα να ψωφήσεις το method αυτό.

Πές πάντως τι έπαιξε έχει ενδιαφέρον.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d-->--- s+:+ a- C++(+++) BILS++++$ P--- L++++>+++++ E--- W+++ N+ o+ K w--
O M+ V-- PS++>+++ PE- Y++ PGP++ t+ 5+ X+ R* tv b++ DI- D+ G+++ e+++>++++ h r++ y++
------END GEEK CODE BLOCK------

"UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity." -- Dennis Ritchie
Post Reply

Return to “Προγραμματισμός”