Re: How can I stop an anonymous thread?

Discussion in 'Java' started by Dave Glasser, Jun 28, 2003.

  1. Dave Glasser

    Dave Glasser Guest

    "George W. Cherry" <> wrote
    on Sat, 28 Jun 2003 02:13:02 GMT in comp.lang.java.programmer:

    >I tend to use anonymous objects (and therefore anony-
    >mous threads) quite often. But how does one stop an
    >anonymous thread. In the following program I invoke
    >the garbage collector to stop the unreferenced Timer
    >thread?
    >
    >How would you prefer to write this program?
    >
    >George W. Cherry
    >
    >import java.util.Timer;
    >import java.util.TimerTask;
    >
    >public class AlarmClock {
    > public static void main(String[] args) {
    > int delay = Integer.parseInt( args[0] );
    > System.out.println(
    > "Setting alarm clock to go off " + delay + " seconds from now."
    > );
    > new Timer().schedule(
    > new TimerTask() {
    > public void run() {
    > System.out.println("Ding-A-Ling! Time to get up!");
    > }
    > },
    > delay*1000
    > );
    > System.gc(); //To shut down the anonymous Timer thread.
    > }//end main method
    >}//end AlarmClock class
    >


    First, invoking the garbage collector will not stop an anonymous
    thread, nor will it arbitrarily stop any running thread; if it did
    then Java would pretty worthless.

    Your anonymous thread could be given a reference to a variable outside
    of itself (in the enclosing class) which it could check periodically
    to see if it should continue running.

    Or, you could just hold on to a reference to your Timer object and
    call its cancel method when/if you want to stop it:

    Timer t = new Timer().schedule(
    ...

    t.cancel();


    ----
    Check out QueryForm, a free, open source, Java/Swing-based
    front end for relational databases.

    http://qform.sourceforge.net
     
    Dave Glasser, Jun 28, 2003
    #1
    1. Advertising

  2. "Dave Glasser" <> wrote in message
    news:...
    > "George W. Cherry" <> wrote
    > on Sat, 28 Jun 2003 02:13:02 GMT in comp.lang.java.programmer:
    >
    > >I tend to use anonymous objects (and therefore anony-
    > >mous threads) quite often. But how does one stop an
    > >anonymous thread. In the following program I invoke
    > >the garbage collector to stop the unreferenced Timer
    > >thread?
    > >
    > >How would you prefer to write this program?
    > >
    > >George W. Cherry
    > >
    > >import java.util.Timer;
    > >import java.util.TimerTask;
    > >
    > >public class AlarmClock {
    > > public static void main(String[] args) {
    > > int delay = Integer.parseInt( args[0] );
    > > System.out.println(
    > > "Setting alarm clock to go off " + delay + " seconds from now."
    > > );
    > > new Timer().schedule(
    > > new TimerTask() {
    > > public void run() {
    > > System.out.println("Ding-A-Ling! Time to get up!");
    > > }
    > > },
    > > delay*1000
    > > );
    > > System.gc(); //To shut down the anonymous Timer thread.
    > > }//end main method
    > >}//end AlarmClock class
    > >

    >
    > First, invoking the garbage collector will not stop an anonymous
    > thread, nor will it arbitrarily stop any running thread; if it did
    > then Java would pretty worthless.


    But "System.gc();" works! Run it and see. Then comment out
    the invocation of the garbage collector, compile it, and run it;
    and you'll see that the program "hangs". In all fairness to your
    claim, Dave, an invocation of the gc on an anonymous thread
    that HAS REACHED THE END of its run method will collect
    the thread. So, both my statement in my original post and your
    statement are a trifle careless. I'm glad to be corrected.

    > Your anonymous thread could be given a reference to a variable outside
    > of itself (in the enclosing class) which it could check periodically
    > to see if it should continue running.


    Yes, but if the "anonymous" thread is given a reference, then
    it's not anonymous.

    > Or, you could just hold on to a reference to your Timer object and
    > call its cancel method when/if you want to stop it:
    >
    > Timer t = new Timer().schedule(


    Your idea is correct, but the line above is not correct because
    the types on the lhs and rhs of "=" are not compatible. One
    would have to do something like I do below, which is correct
    syntactically and semantically.

    > ...
    >
    > t.cancel();


    Yes, that's a way to stop the thread and it's probably the best
    way. I show the rewritten program below. Thanks for straight-
    ening me out on the incompletness of my comment in the orig-
    inal program. The rewritten program is below (but, of course,
    the Timer thread is no longer anonymous).

    George W. Cherry

    import java.util.Timer;
    import java.util.TimerTask;

    public class AlarmClock {
    public static void main(String[] args) {
    int delay = Integer.parseInt( args[0] );
    System.out.println(
    "Setting alarm clock to go off " + delay + " seconds from now."
    );
    final Timer timer = new Timer();
    timer.schedule(
    new TimerTask() {
    public void run() {
    System.out.println("Ding-A-Ling! Time to get up!");
    timer.cancel();
    }
    },
    delay*1000
    );
    }//end main method
    }//end AlarmClock class
     
    George W. Cherry, Jun 28, 2003
    #2
    1. Advertising

  3. Dave Glasser

    Dave Glasser Guest

    "George W. Cherry" <> wrote
    on Sat, 28 Jun 2003 04:33:11 GMT in comp.lang.java.programmer:

    >
    >"Dave Glasser" <> wrote in message
    >news:...
    >> "George W. Cherry" <> wrote
    >> on Sat, 28 Jun 2003 02:13:02 GMT in comp.lang.java.programmer:
    >>
    >> >I tend to use anonymous objects (and therefore anony-
    >> >mous threads) quite often. But how does one stop an
    >> >anonymous thread. In the following program I invoke
    >> >the garbage collector to stop the unreferenced Timer
    >> >thread?
    >> >
    >> >How would you prefer to write this program?
    >> >
    >> >George W. Cherry
    >> >
    >> >import java.util.Timer;
    >> >import java.util.TimerTask;
    >> >
    >> >public class AlarmClock {
    >> > public static void main(String[] args) {
    >> > int delay = Integer.parseInt( args[0] );
    >> > System.out.println(
    >> > "Setting alarm clock to go off " + delay + " seconds from now."
    >> > );
    >> > new Timer().schedule(
    >> > new TimerTask() {
    >> > public void run() {
    >> > System.out.println("Ding-A-Ling! Time to get up!");
    >> > }
    >> > },
    >> > delay*1000
    >> > );
    >> > System.gc(); //To shut down the anonymous Timer thread.
    >> > }//end main method
    >> >}//end AlarmClock class
    >> >

    >>
    >> First, invoking the garbage collector will not stop an anonymous
    >> thread, nor will it arbitrarily stop any running thread; if it did
    >> then Java would pretty worthless.

    >
    >But "System.gc();" works! Run it and see. Then comment out
    >the invocation of the garbage collector, compile it, and run it;
    >and you'll see that the program "hangs".


    Here's what the Javadoc for the Timer class says:

    "After the last live reference to a Timer object goes away and all
    outstanding tasks have completed execution, the timer's task execution
    thread terminates gracefully (and becomes subject to garbage
    collection). However, this can take arbitrarily long to occur. By
    default, the task execution thread does not run as a daemon thread, so
    it is capable of keeping an application from terminating. If a caller
    wants to terminate a timer's task execution thread rapidly, the caller
    should invoke the the timer's cancel method."

    It's not "hung", so to speak; it's waiting for the Timer's thread to
    terminate, which, as the Javadoc says, can take an "arbitrarily long"
    time. I'll admit though that the difference between that and being
    hung is subtle. :)


    >In all fairness to your
    >claim, Dave, an invocation of the gc on an anonymous thread
    >that HAS REACHED THE END of its run method will collect
    >the thread. So, both my statement in my original post and your
    >statement are a trifle careless. I'm glad to be corrected.


    You're still being a trifle careless. You can't invoke gc() "on" a
    particular thread. If a thread, or any object is eligible to be
    garbage collected, it may be collected when you call gc(), and then
    again, it may not be. It's just the luck of the draw that your call to
    gc() causes your app to terminate. If it was a larger app that used
    more memory, the effect might not be the same.

    >
    >> Your anonymous thread could be given a reference to a variable outside
    >> of itself (in the enclosing class) which it could check periodically
    >> to see if it should continue running.

    >
    >Yes, but if the "anonymous" thread is given a reference, then
    >it's not anonymous.


    Sorry George, wrong again. In Java, the word "anonymous" describes a
    class that has no name, not an object. And an instance of an anonymous
    class can certainly have a reference, in fact most probably do. If I
    do:

    button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    ...
    }
    });

    I've just passed an instance of an anonymous class to a JButton's
    addActionListener method. It's definitely an anonymous class, and the
    JButton is definitely holding a (indirect) reference to the instance I
    just passed it.
    >
    >> Or, you could just hold on to a reference to your Timer object and
    >> call its cancel method when/if you want to stop it:
    >>
    >> Timer t = new Timer().schedule(

    >
    >Your idea is correct, but the line above is not correct because
    >the types on the lhs and rhs of "=" are not compatible. One
    >would have to do something like I do below, which is correct
    >syntactically and semantically.


    Oops!

    >
    >> ...
    >>
    >> t.cancel();

    >
    >Yes, that's a way to stop the thread and it's probably the best
    >way. I show the rewritten program below. Thanks for straight-
    >ening me out on the incompletness of my comment in the orig-
    >inal program. The rewritten program is below (but, of course,
    >the Timer thread is no longer anonymous).


    It never was, George, as I explained above. :) The TimerTask, however,
    was an instance of an anonymous class, because the subclass of
    TimerClass you created had no name. The compiled class file for that
    class is probably AlarmClock$1.class.



    ----
    Check out QueryForm, a free, open source, Java/Swing-based
    front end for relational databases.

    http://qform.sourceforge.net
     
    Dave Glasser, Jun 28, 2003
    #3
  4. "Dave Glasser" <> wrote in message
    news:...
    > "George W. Cherry" <> wrote
    > on Sat, 28 Jun 2003 02:13:02 GMT in comp.lang.java.programmer:
    > First, invoking the garbage collector will not stop an anonymous
    > thread, nor will it arbitrarily stop any running thread; if it did
    > then Java would pretty worthless.


    Of course. What's happening here is that forcing a garbage collection is
    causing the Timer to be collected. Its finalizer is recognizing that there
    are no more tasks to be run and thus killing the thread. Since one can't
    count on either:

    A call to System.gc() collecting any particular object, or

    Finalizers running promptly

    this isn't a particularly good way to stop the thread.

    The OP is correct that if you start a Thread and don't keep a reference to
    it, you've lost control of it. Don't do that.

    >
    > Your anonymous thread could be given a reference to a variable outside
    > of itself (in the enclosing class) which it could check periodically
    > to see if it should continue running.
    >
    > Or, you could just hold on to a reference to your Timer object and
    > call its cancel method when/if you want to stop it:
    >
    > Timer t = new Timer().schedule(
    > ...
    >
    > t.cancel();
    >


    Or you could tell the Timer to create a daemon thread:

    new Timer(true)

    which would allow the process to exit while the thread still lived.
     
    Mike Schilling, Jun 28, 2003
    #4
  5. Dave Glasser

    Dave Glasser Guest

    "Mike Schilling" <> wrote on Sat, 28 Jun
    2003 15:24:36 GMT in comp.lang.java.programmer:


    >Or you could tell the Timer to create a daemon thread:
    >
    > new Timer(true)
    >
    >which would allow the process to exit while the thread still lived.



    I was thinking the same thing, but I tried it with George's example
    program and the app exited immediately, before the TimerTask was
    executed. When a Timer's thread is a daemon thread, the process will
    exit regardless of any pending scheduled tasks there are. So if you're
    going to make a Timer a daemon thread, you'd better rely on something
    else to keep the app alive.



    ----
    Check out QueryForm, a free, open source, Java/Swing-based
    front end for relational databases.

    http://qform.sourceforge.net
     
    Dave Glasser, Jun 28, 2003
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. mimisam
    Replies:
    3
    Views:
    461
    =?ISO-8859-1?Q?=D2scar_P=E9rez_del_Campo?=
    Oct 31, 2003
  2. Son KwonNam
    Replies:
    11
    Views:
    2,607
    mr_organic
    Apr 9, 2004
  3. Benji
    Replies:
    34
    Views:
    1,178
    pkriens
    Oct 28, 2005
  4. Reporter
    Replies:
    3
    Views:
    477
    Mike Schilling
    May 12, 2007
  5. Replies:
    1
    Views:
    223
Loading...

Share This Page