"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