Threads question

R

Richard

Hi all

I was looking at some code about threads and am a bit stuck. Any advice
will be appreciated. I have two questions.

First the background....

I have two buttons on a form called one and two. When you click button
one it outputs the numbers 0 to 99 every tenth of a second. THis is on
a separate thread. I have a second button which is used to cancel the
buttonOne action. I have done this with a variable check as recommended
by Sun in the Thread class file under the stop method

"Many uses of <code>stop</code> should be replaced by code that simply
modifies some variable to indicate that the target thread should stop
running. The target thread should check this variable regularly, and
return from its run method in an orderly fashion if the variable
indicates that it is to stop running."

And now the questions....

My first question is what happens to this thread when I return from the
run method? Am I correct in thinking that when the run method of a
thread is left it goes into the dead state and will just die?

My second question is about the checker boolean that Sun recommends
using to stop a thread. This works in my example because I am using two
inner classes so both the start and stop button actions can see the
'keepRunning' variable. Is there a pattern or an example of how I
could do this will three separate classes. I was thinking of passing
the variable around and checking it but this seemed to have quite a lot
of coupling. Is there a listener interface I could use for it? Am I
going along the right lines? Any advice on this would be appreciated
because I want to try and write **good** code.


Here is the code I have written to demostrate..

------------------------------------------------------------------

package test;

import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main extends JFrame{

private boolean keepRunning = true;

public Main() {
JPanel panel = new JPanel();

JButton one = new JButton();
one.setAction(new oneAction());

JButton two = new JButton();
two.setAction(new twoAction());

panel.add(one);
panel.add(two);

getContentPane().add(panel);

setSize(100, 100);
setLocation(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);

}

private class oneAction extends AbstractAction implements Runnable {
public oneAction(){
super("one");
}
public void actionPerformed(ActionEvent e) {
new Thread(this).start();
}

public void run() {
for (int i = 0; i < 100; i++){
if (keepRunning){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(">>" + i);
} else {
return;
}
}
}
}

private class twoAction extends AbstractAction {

public twoAction(){
super("two");
}
public void actionPerformed(ActionEvent e) {
keepRunning = false;
System.out.println(">>" + "should stop button one action");
}
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new Main();
}});
}
}

---------------------------------------------------------------

Thanks for any help

Richard

--
 
O

opalpa

When run exits the Thread instance will be garbage collected. You can
find out about this if you add a method like this:

protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalized");
}

---

I think passing around the variable is bad but making a method which
sets the value of the variable to false seems good enough to me.

---

One thing that I find unusual about your code is that you start a
Thread for every hit of button 1 and if someone hits it more than once
then they will have the print out thing happening multiple times
simultaneously. Is that what you were looking to do? Hitting button 2
stops all the Threads started with button 1 hits.

Opalinski
(e-mail address removed)
http://www.geocities.com/opalpaweb/
 
T

Thomas Hawtin

Richard said:
Hi all

I was looking at some code about threads and am a bit stuck. Any advice
will be appreciated. I have two questions.

First the background....

I have two buttons on a form called one and two. When you click button
one it outputs the numbers 0 to 99 every tenth of a second. THis is on
a separate thread. I have a second button which is used to cancel the
buttonOne action. I have done this with a variable check as recommended
by Sun in the Thread class file under the stop method

"Many uses of <code>stop</code> should be replaced by code that simply
modifies some variable to indicate that the target thread should stop
running. The target thread should check this variable regularly, and
return from its run method in an orderly fashion if the variable
indicates that it is to stop running."

And now the questions....

My first question is what happens to this thread when I return from the
run method? Am I correct in thinking that when the run method of a
thread is left it goes into the dead state and will just die?

It goes into the terminated state.The Thread object can then be garbage
collected.
My second question is about the checker boolean that Sun recommends
using to stop a thread. This works in my example because I am using two
inner classes so both the start and stop button actions can see the
'keepRunning' variable. Is there a pattern or an example of how I
could do this will three separate classes. I was thinking of passing
the variable around and checking it but this seemed to have quite a lot
of coupling. Is there a listener interface I could use for it? Am I
going along the right lines? Any advice on this would be appreciated
because I want to try and write **good** code.

You've got to keep it somewhere. You might want to start be
self-encapsulating it with get and set methods, and being explicit which
object you are calling those methods on.
public class Main extends JFrame{

No need to extend JFrame.
private boolean keepRunning = true;

You should at least make this variable volatile.
private class oneAction extends AbstractAction implements Runnable {

Class names should have initial caps. It's a good idea for each class to
only do one thing, so use a separate class for the Runnable.
public void actionPerformed(ActionEvent e) {
new Thread(this).start();
}

Depending upon what you want to do, you may find javax.swing.Timer
useful. In particular, you shouldn't modify the GUI off the Event
Dispatch Thread (EDT).
Thread.sleep(100);

Sleeping means that the thread can't be told to exit (without an
interrupt, or worse). It's better to wait on a variable.
} catch (InterruptedException e) {
e.printStackTrace();
}

If you've been interrupted, that probably means you should stop what you
are doing. Don't just do the minimum to keep the compiler happy.

Tom Hawtin
 
R

Richard

Thanks for your help so far.

I did not really think about the one button being pressed multiple
times. It is only a test program for myself so it doesnt really matter.

I was thinking of using multiple classes and a variable to stop the
thread. Here is my design with a super class that controlls the
variable's value.


abstract wrapper class extends AbstractAction
| (with get/set methods for checkVar)
|
|
|------ StartAction (with ActionPerformed implemented
| and examines variable in super class to start)
|
|
|------ StopAction (with ActionPerformed implemented
and examines variable in super class to stop)

Is this clear?

Is this a good design?

I am just conscious about my design when it come to programming. I want
to get into good techniques now while Im still a relative beginner. If
anyone know of any good resources for design these would also be useful.

Thanks

Richard
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top