Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Re: How to stop a thread?

Reply
Thread Tools

Re: How to stop a thread?

 
 
John C. Bollinger
Guest
Posts: n/a
 
      08-27-2003
Lee Francis Wilhelmsen wrote:
> Hi
>
> I have a mathematical algorithm that takes a while to complete. It runs in
> it's own thread. To stop the thread I interrupt the thread and then set the
> thread variable to null. The following code has been adapted from the
> program and is presented in the following class. The Worker class that does
> the work isn't really relevant here.


On the contrary, the details of the worker class are very relevant.

> class MyClass {
> private Thread t = null;
>
> public void go() {
> SwingUtilities.invokeLater(new Runnable() {
> public void run() {
> MyClass.this.t = new Thread() {
> public void run() {
> // the work is done in the worker
> Worker worker = new Worker():
> worker.doWork();
> }
> }
> }
> }
> }
>
> public void quit() {
> // user want to interrupt operation
> if (MyClass.this.t != null) {
> MyClass.this.t.interrupt();
> MyClass.this.t = null;
> }
> }
> }
>
> Does this look ok?


No.

In the first place, take SwingUtilities out of the picture. To start a
new Thread just instantiate it and invoke its start() method. That's
not a problem even in a Swing / AWT event handler. If that thread wants
to manipulate the GUI, then it should use SwingUtilities to insert those
manipulations into the AWT event handling thread.

In the second place, you should need to qualify "this" with MyClass,
especially in your quit() method.

> I'm having trouble getting the Worker.doWork() algorithm
> to terminiate it's operation?


Is that a question?

In the third place, I'm not surprised if you are having trouble getting
Worker.doWork() to terminate. As I said above, it's details are very
relevant to the question. Interrupting a Thread sets a flag in that
Thread's state, but there are only a few methods in the entire platform
API that are directly affected (Thread.sleep() and Object.wait() being
two of the more relevant ones). If you want your algorithm to be
interruptible then you have to code for it.

> I'm thinking fairly general here. The
> algorithm contains a loop. Should each iteration check Thread.interrupted()
> and break if true? Should it throw an InterruptedException? Both (depending
> the thread state)


A looping algorithm is the easiest kind for which to enable
interruption. Once for every n iterations (n >= 1) you check the
current thread's interrupted status and terminate if it is set. There
are multiple ways to do that. One way is to insert a Thread.sleep(1);
this will throw an InterruptedException if the current Thread has been
interrupted, and it will also ensure that other Threads in the JVM have
a chance to run. You can also check Thread.interrupted() or
Thread.currentThread.isInterrupted() [be careful, the semantics are
slightly different] to obtain the current Thread's interrupted status at
any time.

It is not necessary to throw an exception when the thread is
interrupted, but if you want it to stop then you must make sure that its
run method terminates. That can happen normally or via an exception.

Although Java provides the Thread.interrupt() mechanism, it is also
possible to create a similar feature by defining your own flag to be set
when execution is supposed to terminate.

>
> This is what I'm using today and it isn't working.


Very likely you are either interrupting the wrong Thread or your
interruption checking is incorrect. Or it _is_ working and you have a
different problem than you think you do. Show us the appropriate part
of Worker's code if you want a real analysis. Even better, develop a
complete, cut down example that demonstrates your problem.

As an aside, it would be more elegant if Worker implemented Runnable;
then you wouldn't need a separate, anonymous Runnable. Furthermore, you
should probably take measures against your calculation being started
multiple times, because you only keep track of the Thread of the most
recent one.


John Bollinger
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
Lee Francis Wilhelmsen
Guest
Posts: n/a
 
      08-28-2003
> On the contrary, the details of the worker class are very relevant.

Yes, but I was talking about the actual algorithm. Sorry for any
confusion.

> In the first place, take SwingUtilities out of the picture. To start a
> new Thread just instantiate it and invoke its start() method. That's
> not a problem even in a Swing / AWT event handler. If that thread wants
> to manipulate the GUI, then it should use SwingUtilities to insert those
> manipulations into the AWT event handling thread.


The algorithm updates a UI model for a progress bar. I thought I needed to
run the code in SwingUtilities.invokeLater(). So what you are saying is move
this invokeLater call to the actual code updating the progress bar model? I
didn't want to clutter the algorithm with call to UI code.

> In the second place, you should not need to qualify "this" with MyClass,
> especially in your quit() method.


Why is that a problem? Is it a problem or just a preference?

> In the third place, I'm not surprised if you are having trouble getting
> Worker.doWork() to terminate. As I said above, it's details are very
> relevant to the question. Interrupting a Thread sets a flag in that
> Thread's state, but there are only a few methods in the entire platform
> API that are directly affected (Thread.sleep() and Object.wait() being
> two of the more relevant ones). If you want your algorithm to be
> interruptible then you have to code for it.


Ok, the application running this algorithm is a GUI with a start and stop
button. When the user presses the stop button then the quit() code is
called. What you are saying is that it's unessessary and I should instead
implement a worker.stop() method or something. I guess, that means that the
worker must be referenced in the class and implement the Runnable interface.

> > I'm thinking fairly general here. The
> > algorithm contains a loop. Should each iteration check

Thread.interrupted()
> > and break if true? Should it throw an InterruptedException? Both

(depending
> > the thread state)

>
> A looping algorithm is the easiest kind for which to enable
> interruption. Once for every n iterations (n >= 1) you check the
> current thread's interrupted status and terminate if it is set. There
> are multiple ways to do that. One way is to insert a Thread.sleep(1);
> this will throw an InterruptedException if the current Thread has been
> interrupted, and it will also ensure that other Threads in the JVM have
> a chance to run. You can also check Thread.interrupted() or
> Thread.currentThread.isInterrupted() [be careful, the semantics are
> slightly different] to obtain the current Thread's interrupted status at
> any time.


This is what I'm doing (Thread.interrupted), but it never returns true. The
loop also calls a Thread.yield().

> > This is what I'm using today and it isn't working.

>
> Very likely you are either interrupting the wrong Thread or your
> interruption checking is incorrect. Or it _is_ working and you have a
> different problem than you think you do.


Well I have verified that the thread is the same. I give the thread a name
and ask for it's name before a call to isInterrupted() or interrupt() is
made.

> Show us the appropriate part of Worker's code if you want a real analysis.

Even better, develop a
> complete, cut down example that demonstrates your problem.


Ok, I'll try:

public class Worker {
public void doWork(String[] domains) throws InterruptedException {
try {
doThis();
}
catch(Throwable e) {
logger.severe("Unknown exception in worker " + e.getMessage());
throw new InterruptedException(e.getMessage());
}

private void doThis() throws InterruptedException {
for (some iterations) {
Thread.yield();
....
if (Thread.interrupted())
throw new InterruptedException("Reporting interrupted");
}
}
}

> As an aside, it would be more elegant if Worker implemented Runnable;
> then you wouldn't need a separate, anonymous Runnable. Furthermore, you
> should probably take measures against your calculation being started
> multiple times, because you only keep track of the Thread of the most
> recent one.


But what if the code was already implemented and I had no control over it.
Should I create an Adapter class that implements a Runnable interface?
Should the worker have implemented Runnable from the start? I would have
preferred to keep threading issues out of the main algorithm so I can test
it easier (with JUnit etc). However, I see this can't be done if I want it
to be able to quit before it's finished.

Regards
Lee Francis


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to stop java service with command line parameter '-stop'? Will Java 1 11-02-2004 03:32 PM
f2.8 vs f3.7- Is it one stop or 2 stop difference zxcvar Digital Photography 12 05-20-2004 06:28 PM
How to stop a thread without using stop() Son KwonNam Java 11 04-09-2004 08:01 PM
Q. My browser doesn't stop, when I click on STOP. Jim Jones Computer Support 7 02-03-2004 09:47 PM
Stop Debugging doesn't stop in ASP.NET Matt Theule ASP .Net 7 07-24-2003 07:38 PM



Advertisments