Προς το περιεχόμενο

[JAVA] how to destroy a thread?


JPG

Προτεινόμενες αναρτήσεις

Δημοσ.

Βασικά δεν είμαι σίγουρος τι θέλει να κάνει ο jpg το μήνυμά του το διάβασα ακροθιγώς (λόγω greeklish) πάντως για να σταματήσει ένα thread καλύτερα είναι να μη χρησιμοποιείται η stop() μέθοδος.

 

Αν αυτό που πρέπει να γίνει είναι το

 

Με αλλα λογια..ενa thread αρχιζει να κανει κατι..με το που αρχιζει ,,,παραλληλα αρχιζουμε και μετραμε τον χρονο..αν ο χρονος ξεπερασει το οριο ..το Thread Πεθανει...

 

τότε το καλύτερο είναι κάτι σαν

 

>
class Destroyer extends TimerTask
{
    private Thread thread;

    public Destroyer(Thread thread)
    {
        this.thread = thread;
        thread.start();
        thread.join(10000);    // Wait for ten seconds.

        // Get here when thread reaches 10 seconds or when thread finishes what it's doing
        if (thread.isAlive())
        {
            thread.interrupt();
        }
    }

    public void run()
    {
       // Do stuff here
    }

}

 

Δημοσ.

Μερικες παρατηρησεις γιατι ειναι λιγο μπερδεμα!

Δεν χρειαζετει το TimerTask σε αυτη περιπτωση.

Επειδη αναφερεται το join() στον παραπανω κωδικα εχουμε τον Destroyer o Οποιος δεχετε τον Despatcher..τον κανει start..αρχιζει ο dispatcher να κανει αυτο που κανει..παρολα αυτα οταν του ζητηθει να κανει join...Πρεπει να υπαρχει προσοχη σε πιο thread..θα κανει suspend! Εδω μαλλον θελει λιγο προσοχη κωδικας.

 

 

O despatcher θα πρεπει να κανει suspend τον Destroyer για χρονο ισο με το TIME_LIMIT.

Το οποιο σωστα συμφωνα με τον Μaster Πανο το κανουμε το join (1000) αν ο despatcher εχει τελειωσει επιτυχως θα εχει πεθανει επιτυχως! Δεν ξερω πως θα συμπεριφερθει σε περιπτωση που φαει exceptioon και ιδιαιτερα αν ερθει καποιο Ι/Ο exception στον despatcher ...εκει κοιμαται τον υπνο του δικαιου.

 

κατι σαν

>
try{
thread.join(TIME_LIMIT);
}catch(InterruptedException ex){
 System.out.println("Someone is trying to wake me up");
}

 

Δημοσ.

Emfanizomai kai pali me mia javaporia. <img src="http://www.insomnia.gr/ubbthreads/images/graemlins/smile.gif" alt="" />

 

Simera to proi arxisa na grafo ena sistima, meros tou opoiou einai o parakato kodikas.

O skopos aftou tou sistimatos einai na mporei na ginei antallagi dedomenon, ipo morfi minimaton, anamesa se pola kai diaforetika antikeimena. Afta ta antikeimena tha prepei apla na kanoun implement to interface Client, to opoio exei mono mia methodo stin ousia, tin incoming(Message).

 

Yparxei enas kentrikos mixanismos, ston opoio kapios stelnei to minima. Tote dimiourgite ena instance tou Dispatcher, o opoios analambanei na apostilei to minima, mesa se ena prokathorismeno apo to minima xroniko orio (message.timeout).

Yparxei loipon ena TimerTask, to opoio analambanei na katastrepsei ton Dispatcher an den exei teliosei tin douleia tou mesa se afto to xroniko orio. Pos omos tha katastrepso ton Dispatcher?

 

H methodos incoming tou Client einai telios agnosti. Den kseroume poso tha kathisterisei. Oute kai gia poio logo tha kathisterisei. Ara to na kalesoume apla tin interrupt, den tha doulepsei.

 

>

import java.util.*;

public class Dispatcher extends Thread{
	private Message message;
	private Timer timer;

	public Dispatcher(Message message){
		this.message = message;
		timer = new Timer();
		timer.schedule(new Destroyer(this), message.getTimeOut());
	}

	public void run(){
		Client c = message.getTo();
		c.incoming(message);	//  <--- edo o dispatcher kalei tin methodo incoming()
	}
}

class Destroyer extends TimerTask{
	private Thread thread;
	
	public Destroyer(Thread thread){
		this.thread = thread;
	}
	
	public void run(){
		thread.interrupt();	//  <--- ti prepei na ginei edo, anti gia tin interrupt?
	}
}

Δημοσ.

O παραπάνω κώδικας είναι απλώς ένα παράδειγμα για το πως μπορεί να γίνει, δεν εγγυούμαι ότι θα τρέξει χεχε.

 

Επιπλέον δε χρειάζεται timer διότι η μέθοδος join κάνει αυτό που θέλουμε. Αν η thread έχει τελειώσει επιτυχώς τότε θα έχει πεθάνει επιτυχώς, διαφορετικώς μετά από το TIME_LIMIT την πεθαίουνε εμείς θέλει δε θέλει χεχε.

 

Για το exception αυτό που θα μπορούσαμε να κάνουμε είναι να έχουμε ένα finally κομμάτι κώδικα και να θέτουμε τη thread σε null.

Δημοσ.

λοιπον το θεμα ειναι πιο πολυπλοκο I think! ακομα και το παραπανω Link δεν λεει πολλα!

 

Στην αρχη νομιζα οτι βρηκα την λυση με τον TimerTask παρολα αυτα εκανα λαθος!

Αν εχω καταλαβει καλα εχουμε το εξης προβλημα!

 

Θελουμε ενα time constraint σε καποιο Thread!

Με αλλα λογια..ενa thread αρχιζει να κανει κατι..με το που αρχιζει ,,,παραλληλα αρχιζουμε και μετραμε τον χρονο..αν ο χρονος ξεπερασει το οριο ..το Thread Πεθανει...

Η περιπτωση που φαει ενα exception με αναλογο exception handling..το κανουμε Kill η whatever!

 

Aυτο που νομιζω οτι τελικα ειναι η λυση ειναι η εξης!

Events

Δηλαδη: Με το που αρχηζει ο worker να κανει κατι παραλληλα δημοουργειται ενα αλλο Thread(Timer) το οποιο αρχιζει να μετραει τον χρονο. Αν ο χρονος περασει ο Timer κανει dispatch ενα event πχ (TimeENDED) , το πιανει ο worker με τον αντιστοιχο Εvent Handler και κανει Thread.Stop (Συγκεκριμενα θα προτεινα να κανεις implement to Runnable Interface , να τρεξει μια fora h RUN και να πεθανει).

 

Πως σας φαινεται αυτο! Αν θελετε το συζηταμε και με κωδικες!

Δεν ξερω αυτη την στιμγη για μενα αυτη ειναι η μονη λυση!

Ο κωδικας παραπανω δεν θα παιξει..σωστα!

 

 

Δημοσ.

ξερεις τι με απασχολει? και εκανα και μερικα test και ειδα οτι δεν συμπεριφερεται σωστα!

Το context των thread... στην Join.. ποιο ειναι το target και ποιο το current!

 

Δημοσ.

χε! δυστηχως σβηστικε...αν θυμαμαι καλα ειχα μια main..

εκει εκανα

 

Thread t = new AThread();

Thread t2 = new BThread();//ypoklaseis thread kai oi 2

 

t.start();

t2.start();

t2.join();

 

Perimena to Join να παιξει!

 

Δεν ξερω αν επρεπε να κανω το εξης!

t.start();

t.join();

t2.start();

t2.join();

 

 

Δημοσ.

Απο ότι έχω καταλάβει εγώ και σύμφωνα με το API της java για την join: Waits for this thread to die.

Δηλαδή έστω οτι έχουμε 2 threads τα οποία τρέχουν αυτή την στιγμή. ʼν το thread1 καλέσει μέσα στην run() του την thread2.join(); τότε το thread1 θα μπλοκαρηστεί μέσα στην join() του thread2, μέχρι το thread2 να πεθάνει. ʼν το thread1 καλέσει δηλαδή την δικιά του join() θα μπλοκαρηστεί μέσα της για πάντα (Έτσι πιστέυω, δεν το έχω δοκιμάσει).

 

Το θέμα είναι αλλού όμως. Η απορία μου είναι στο πώς καταστρέφεις ενα thread, οταν αυτό είναι μπλοκαρισμένο μέσα σε μια μέθοδο. Για παράδειγμα: το thread του dispatcher έχει καλέσει την μέθοδο incoming(); ενός object. Έστω οτι η incoming() αργεί να εκτελεστεί. ʼρα το thread του dispatcher θα βρήσκεται μέσα στην incoming() (θα μπλοκαρηστεί κατα κάποιο τρόπο). Η κλήση της interrupt(); απο τον Destroyer για thread του Dispatcher, ίσως δεν θα κάνει τίποτα.

 

Στο link του Γηρυόνη, λέει κάπου: What if a thread doesn't respond to Thread.interrupt?

 

Αν κοιτάξεται και στο API, θα δείτε οτι δεν βοηθάει στην προκειμένη περίπτωση η interrupt.

 

Με άλλα λόγια δεν υπάρχει τρόπος να σταματήσεις την εκτέλεση ενος thread όταν αυτό έχει μπλοκαρηστεί μεσα σε μια μέθοδο. Εκτός και αν αυτή η μέθοδος είναι μια απο αυτές που αναφέρονται εδώ:

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.

If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.

 

Στις παραπάνω περιπτώσεις απλά κάνοντας handle το Exception μπορείς να βγείς απο την run τους και όλα είναι μια χαρά. Τι γίνεται όμως αν έχει μπλοκαρηστεί μέσα σε μια οποιαδήποτε άλλη μέθοδο;

Δημοσ.
apoc

said:

t.start();

t2.start();

t2.join();

Αυτές οι 3 γραμμές θα έκαναν το main thread να κάνει start στο t και t2 και μετά να περιμένει μέχρι να παιθάνει το t2.

 

apoc

said:

t.start();

t.join();

t2.start();

t2.join();

Αν έκανες αυτό, το main thread θα έκανε start στο t και θα το περίμενε να παιθάνει. Μετά θα έκανε το ίδιο και για το t2.

 

Και στις δύο περιπτώσεις μόλις θα ολοκήρονόντουσαν αυτά, το main thread θα ολοκλήρωνε την εκτέλεση της main() και θα τερματιζόταν.

Δημοσ.
JPG

said:

Α ʼρα το thread του dispatcher θα βρήσκεται μέσα στην incoming() (θα μπλοκαρηστεί κατα κάποιο τρόπο).

 

Αυτο που περιγραφεις μαλλον εμενα μου ακουγεται οτι εχει φαει exception (γιατι δεν υπαρχει τιποτα αλλο..και socket connnection να ειναι δεν μπορει να περιμενει αιωνια θα φαει timeout απο την αλλη ακρη.

Αρα η μεθοδος θα πρεπει να το πιασει και να το πεταξει στο πιο πανω επιπεδο! σε περιπτωση exception to Τhread θα πεθανει!

 

Παντως συνεχιζω να επιμενω...ελαφρα οτι η λυση των events ειναι πιο καθαρη!

Δημοσ.
JPG

said:

ʼν το thread1 καλέσει μέσα στην run() του την thread2.join(); τότε το thread1 θα μπλοκαρηστεί μέσα στην join() του thread2, μέχρι το thread2 να πεθάνει.

 

Tη join δεν την καλείς μέσα στη run() μέθοδο αλλά έξω από αυτή.

 

Το θέμα είναι αλλού όμως. Η απορία μου είναι στο πώς καταστρέφεις ενα thread, οταν αυτό είναι μπλοκαρισμένο μέσα σε μια μέθοδο.

 

Δεν είμαι σίγουρος αν καταλαβαίνω απολύτως την ερώτησή σου. Αυτό που μπορείς να κάνεις είναι ένα join, ώστε όταν παρέλθει ο χρόνος του join θα μπορέσεις να το σταματήσεις.

 

Στο link του Γηρυόνη, λέει κάπου: What if a thread doesn't respond to Thread.interrupt?

 

Αν δεν απαντάει στο interrupt τότε δεν απαντάει και στo stop() οπότε δεν μπορείς να κάνεις κάτι. Αν δεν απαντάει στο interrupt() τότε υπάρχουνε άλλοι τρόποι για να σκοτώσεις το thread (κλείνεις το αρχείο/socket/σύνδεση στη βάση/κλπ) τα οποία είναι συσχετισμένα με το thread.

 

Αν κοιτάξεται και στο API, θα δείτε οτι δεν βοηθάει στην προκειμένη περίπτωση η interrupt.

 

Με άλλα λόγια δεν υπάρχει τρόπος να σταματήσεις την εκτέλεση ενος thread όταν αυτό έχει μπλοκαρηστεί μεσα σε μια μέθοδο. Εκτός και αν αυτή η μέθοδος είναι μια απο αυτές που αναφέρονται εδώ:

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.

If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.

 

Αν δε σε βοηθήσει η interrupt τότε πίστεψέ με δεν πρόκειται να σε βοηθήσει καμία άλλη μέθοδος. Κοίτα στον παρακάτω κώδικα για να δεις πως σταματάς διάφορα threads χρησιμοποιώντας interrupt και join. Μπορείς να τον προσαρμόσεις σε αυτό που κάνεις.

 

Πάρη

 

Thread t = new AThread();

Thread t2 = new BThread();//ypoklaseis thread kai oi 2

t.start();

t2.start();

t2.join();

Perimena to Join να παιξει!

 

Πρέπει να πιάσεις το InterruptedException, αυτός είναι και ο λόγος που το πιάνουμε, σε περίπτωση που ενοχληθεί η thread την ώρα που κοιμάται.

 

>
public class TestThread extends Thread
{
	public TestThread(String name)
	{
		super(name);
	}
	
	public static void main(String args[])
	{
		TestThread t1 = new TestThread("Thread 1");
		TestThread t2 = new TestThread("Thread 2");
		t1.start();
		t2.start();

		try
		{
			t2.join(3000);
			if (t2.isAlive())
			{
				t2.interrupt();
			}
		}
		catch (InterruptedException ie)
		{
			System.err.println("InterruptedException occured while joing thread: " + ie);
		}
	}
	
	public void run()
	{
		while (true)
		{
			try
			{
				System.out.println("I was called by " + Thread.currentThread().getName());
				Thread.sleep(1000); 
			}
			catch (InterruptedException ie)
			{
				System.err.println(Thread.currentThread().getName() + " is killed!");
				return;
			}
		}
	}
}

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...