Confused about java threading/sleeping

T

Tyler Kellen

Why does this code hang for the specified 5 seconds (in the refresh
thread)before displaying anything? I have the sleep running in a
seperate thread but it causes everything to wait for it. The desired
result I am trying to accomplish here is to add another line of text
to the screen every 5 seconds. I'm not certain how to go about this
though. Any help understanding where I am going wrong here would be
greatly appreciated.

//-->Start Code
import java.applet.Applet;
import java.awt.Graphics;

public class test extends Applet
{
StringBuffer buffer;
refresh r;

public void init()
{
buffer = new StringBuffer();
addItem("initializing... ");
r = new refresh();
}

public void start()
{
addItem("starting... ");
r.start();
}

void addItem(String newWord)
{
buffer.append(newWord);
repaint();
}

public void paint(Graphics g)
{
g.drawString(buffer.toString(), 5, 15);
}

class refresh extends Thread
{
public void start()
{
try { refresh.sleep(5000); } catch(Exception e) { }
addItem("refreshed");
}
}
}
//--> End Code

If I put the refresh start() contents in a while(true) { } loop it
never displays anything. How do I have this loop running but allow
the main thread to continue?

Thanks much,
Tyler Kellen
 
H

Harald Hein

Tyler Kellen said:
Why does this code hang for the specified 5 seconds (in the refresh
thread)before displaying anything? I have the sleep running in a
seperate thread but it causes everything to wait for it. The desired
result I am trying to accomplish here is to add another line of text
to the screen every 5 seconds. I'm not certain how to go about this
though. Any help understanding where I am going wrong here would be
greatly appreciated.

a. You don't mess around with the start() method. Read the Thread API
again, also read the Sun tutorial about using threads.

b. Read about the single-threading behavior of the GUI. You do not
sleep in the event-handler thread, unless you want the GUI to freeze.
 
S

Steve Horsley

Tyler said:
Why does this code hang for the specified 5 seconds (in the refresh
thread)before displaying anything? I have the sleep running in a
seperate thread but it causes everything to wait for it. The desired
result I am trying to accomplish here is to add another line of text
to the screen every 5 seconds. I'm not certain how to go about this
though. Any help understanding where I am going wrong here would be
greatly appreciated.

class refresh extends Thread
{
public void start()
{
try { refresh.sleep(5000); } catch(Exception e) { }
addItem("refreshed");
}
}

There's a big problem. You have overridden the thread's start()
method, so this Thread derivative can never actually be started.
All start() does is putthe calling thread to sleep for 5 secs.

I advise that you do not ever extend Thread. It creates too many
confusions like this mistake. Make your objects Runnable instead.

Steve
 
M

Mark 'Kamikaze' Hughes

Steve Horsley said:
There's a big problem. You have overridden the thread's start()
method, so this Thread derivative can never actually be started.
All start() does is putthe calling thread to sleep for 5 secs.
I advise that you do not ever extend Thread. It creates too many
confusions like this mistake. Make your objects Runnable instead.

There's nothing wrong with extending Thread. He just needs to put
that code in run() instead of start().

Tyler, read java.lang.Thread's javadoc, and the parts of the Java
Tutorial about the Thread lifecycle.
 
J

John C. Bollinger

Mark said:
There's nothing wrong with extending Thread. He just needs to put
that code in run() instead of start().

It depends on what you mean by "wrong." It is a workable solution to
extend Thread by overriding its run() method to define the task the
thread is to perform. In that sense it is not wrong. It is poor
practice to do that, however, because (1) it is the wrong abstraction,
(2) it is somewhat inflexible, and (3) it is easy to muck it up (c.f.
the OP's problem).


John Bollinger
(e-mail address removed)
 
M

Mark 'Kamikaze' Hughes

John C. Bollinger said:
It depends on what you mean by "wrong." It is a workable solution to
extend Thread by overriding its run() method to define the task the
thread is to perform. In that sense it is not wrong. It is poor
practice to do that, however, because (1) it is the wrong abstraction,
(2) it is somewhat inflexible,

These complaints don't make any sense. It's a worker thread.
Subclassing Thread to do work is exactly what you should be doing, and
is the most precise way of saying what it is and what it does.
Implementing Runnable and passing it to a generic Thread object is
useful mainly if you want to subclass something else but also process a
thread, which is almost always a bad idea, leading to giant,
poorly-focused classes.

Why would you need any more "flexibility"? It's a thread. You start
it and it runs until the program ends (well, a correct version would,
Tyler's version will still just run once even if it's in the right
method). You're not going to do anything else with it.

Avoiding subclassing smacks of procedural programming habits. Those
unused to actually using OOP are understandably uncomfortable with
extending the behavior of an object, but that's what it's *for*.
and (3) it is easy to muck it up (c.f.
the OP's problem).

Not reading the documentation will do that. If I fail to read the
documentation for vi, I can't edit text, either. Oh no!
 
X

xarax

/snip/
These complaints don't make any sense. It's a worker thread.
Subclassing Thread to do work is exactly what you should be doing, and
is the most precise way of saying what it is and what it does.

It is generally accepted among the enlightment folks
that subclassing Thread is the wrong way. Get with
the times, you are thinking in the stone-age.
Implementing Runnable and passing it to a generic Thread object is
useful mainly if you want to subclass something else but also process a
thread, which is almost always a bad idea, leading to giant,
poorly-focused classes.

This thinking is either inane or insane, depending on whether
one is trying to analyze it or to design commercial-quality
object-oriented software. STOP IT!
Why would you need any more "flexibility"? It's a thread. You start
it and it runs until the program ends (well, a correct version would,
Tyler's version will still just run once even if it's in the right
method). You're not going to do anything else with it.

Using the Thread constructor that accepts a Runnable is
the correct way. Subclassing Thread is incorrect. Always.
Avoiding subclassing smacks of procedural programming habits.

Total nonsense. Use subclasses where "IS-A" relationship makes
sense. An independent unit of work is a separate notion to the
*kind* of work being performed. "Thread" is the unit of work,
which has nothing to do with the "Runnable", which is the *kind*
of work to be done.
Those
unused to actually using OOP are understandably uncomfortable with
extending the behavior of an object, but that's what it's *for*.

Those who understand OOP know when to use inheritance and
when to use composition. Apparently, you do not.

/snip/
 
M

Mark 'Kamikaze' Hughes

xarax said:
/snip/
It is generally accepted among the enlightment folks
that subclassing Thread is the wrong way. Get with
the times, you are thinking in the stone-age.

You are a loon. I just want you to know that. Now I'm going to put
you in my killfile, because I know you'll never have anything useful to
say.
 
R

Roedy Green

Subclassing Thread is incorrect. Always.

I can think of a case where you would -- e.g. StoppableThread,
creating a kind of thread you can stop gently. You are correct though,
nearly always all you want is a light-weight Runnable.
 
R

Roedy Green

You are a loon. I just want you to know that. Now I'm going to put
you in my killfile, because I know you'll never have anything useful to
say.

I think you are overgeneralising. Just because you did not find that
post helpful does not mean you won't find anything he writes useful.

You are hurting yourself with such a post. It makes you sound like
one of those "entitlement brats" who figures the universe owes them a
solution to every problem neatly wrapped with a bow.
 
C

Chris Smith

Mark said:
These complaints don't make any sense. It's a worker thread.
Subclassing Thread to do work is exactly what you should be doing, and
is the most precise way of saying what it is and what it does.

The trouble is that this isn't true. In fact, it's denying the inherent
difference between a thread (which is part of an implementation of how
to accomplish something) and something to be accomplished. You're then
likely to end up tying the two together, making it difficult to change
your strategy for dealing with concurrent goals in your application.
Implementing Runnable and passing it to a generic Thread object is
useful mainly if you want to subclass something else but also process a
thread, which is almost always a bad idea, leading to giant,
poorly-focused classes.

I agree somewhat; it's certainly a bad idea to try and accomplish too
much from a single class, and certainly both defining a task to
accomplish (possibly with a thread) *and* doing something unrelated in
the same object is a bad idea. I don't think I've ever extended a
subclass while also implementing Runnable (though I could see why it's a
good idea, if there are a number of similar tasks in the application
that could benefit from an inheritance relationship between them).

However, extending Thread has a few disadvantages as a way to define a
task to accomplish. For example, it creates a resource that's tied into
the thread group structure, such that it absolutely has to be run
exactly once. Future design changes to the application are quite likely
to obsolete that peculiar assumption, as well as many others (such as
that the task needs to happen concurrently at all).

Basically, then, the Runnable interface is the best and simplest way to
describe what you're really writing: a task to be accomplished. If you
choose to approach that class, you can very well do so, and Thread has a
convenient constructor for accomplishing this. On the other hand, the
task could be handled by a task scheduling or thread pooling system that
is designed to us Runnable instances to hold its tasks, or it could be
scheduled to run later in another thread via, e.g.,
SwingUtilities.invokeLater. It's that means of avoiding tying yourself
into an implementation that leads to better design and less coupling.
Why would you need any more "flexibility"? It's a thread. You start
it and it runs until the program ends (well, a correct version would,
Tyler's version will still just run once even if it's in the right
method). You're not going to do anything else with it.

I'm not sure what you're getting at. All threads contain infinite loops
and run until the application exits? Isn't that a little limited?
Avoiding subclassing smacks of procedural programming habits. Those
unused to actually using OOP are understandably uncomfortable with
extending the behavior of an object, but that's what it's *for*.

Avoiding subclassing also smacks of an experienced object-oriented
design. Inheritance is certainly not bad, but it is limited. Those
limitations are the biggest pain of all when you've chosen inheritance
just because you can, and played around with an abstraction (for
example, by mixing the concepts of a thread and its target code) to
justify your inheritance in a place where it doesn't belong.

The interesting thing about object-orientation is that it is ultimately
oriented toward polymorphism... but you have to take a few roads to get
there. Early beginners in OO programming tend to see it in terms of
encapsulation of data into classes, missing the rest. Later,
intermediate students of OO programming start to "get" inheritance, and
apply it in far too many places. After some experience there, students
begin to understand where these ideas are appropriate, and where they
are not.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top