Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / March 2004

Tip: Looking for answers? Try searching our database.

Not understandable Thread behaviour

Thread view: 
lonelyplanet999 - 05 Mar 2004 11:55 GMT
Hi,

I found that if I do not include public void main() method in class
extending Thread class, nothing can be output by it's run() method
even if .start() being called on that Thread instance. Why will that
happen ?

For example, for below program, nothing will be output as the program
being run. If I un-comment those lines, I could only see text output
by ot3, ot4 instances. Why ot1 & ot2 cannot print text out to console
?

public class OverloadThread {
 public static void main(String[] args) {
   Thread ot1 = new Thread(), ot2 = new Thread();
//    ORunnable or1 = new ORunnable(), or2 = new ORunnable();
//    Thread ot3 = new Thread(or1), ot4 = new Thread(or2);
   ot1.setName("ot1");
   ot2.setName("ot2");
//    ot3.setName("ot3");
//    ot4.setName("ot4");
   ot1.start();
   ot2.start();
//    ot3.start();
//    ot4.start();
 }
}

class Othread extends Thread {
  public void run() {
    for (int i=0; i<5; i++) {
      System.out.println("OThread."+Thread.currentThread().getName()+".run()");
      this.run("Overload");
    }
  }
  public void run(String s) {
    System.out.println("OThread."+Thread.currentThread().getName()+".run(String)");
  }
}

//class ORunnable implements Runnable {
//  public void run() {
//    for (int i=0; i<5; i++) {
//      System.out.println("ORunnable."+Thread.currentThread().getName()+".run()");
//      this.run("Overload");
//    }
//  }
//  public void run(String s) {
//    System.out.println("ORunnable."+Thread.currentThread().getName()+".run(String)");
//  }
//}

Why Thread instance class (or it's subclass) can only output text to
console when it also includes public void main() method in it's class
definition ?

class MyThread extends Thread {

 public static void main(String[] args) {
   MyThread t = new MyThread();
   t.start();
 }

 public void run() {
   System.out.println("Thread");
 }

}

Running this program produce below output

Thread

:)
Ryan Stewart - 05 Mar 2004 12:41 GMT
> Hi,
>
> I found that if I do not include public void main() method in class
> extending Thread class, nothing can be output by it's run() method
> even if .start() being called on that Thread instance. Why will that
> happen ?

It won't. Your findings are incorrect. There is something else wrong.

> For example, for below program, nothing will be output as the program
> being run. If I un-comment those lines, I could only see text output
> by ot3, ot4 instances. Why ot1 & ot2 cannot print text out to console
> ?

Because below, ot1 and ot2 are instances of java.lang.Thread. Thread's run
method does nothing. I think you meant to make them Othread's.

> public class OverloadThread {
>   public static void main(String[] args) {
[quoted text clipped - 15 lines]
>    public void run() {
>      for (int i=0; i<5; i++) {

System.out.println("OThread."+Thread.currentThread().getName()+".run()");
>        this.run("Overload");
>      }
>    }
>    public void run(String s) {

System.out.println("OThread."+Thread.currentThread().getName()+".run(String)
");
>    }
> }
[quoted text clipped - 3 lines]
> //    for (int i=0; i<5; i++) {
> //
System.out.println("ORunnable."+Thread.currentThread().getName()+".run()");
> //      this.run("Overload");
> //    }
> //  }
> //  public void run(String s) {
> //
System.out.println("ORunnable."+Thread.currentThread().getName()+".run(Strin
g)");
> //  }
> //}
>
> Why Thread instance class (or it's subclass) can only output text to
> console when it also includes public void main() method in it's class
> definition ?

Again, this is not a limitation of a Thread.

> class MyThread extends Thread {
>
[quoted text clipped - 14 lines]
>
> :)
So does the following:

public class Foo {
   public static void main(String[] args) {
       MyThread t = new MyThread();
       t.start();
   }
}

class MyThread extends Thread {
   public void run() {
       System.out.println("Thread");
   }
}
Jon A. Cruz - 05 Mar 2004 16:29 GMT
> Hi,
>
> I found that if I do not include public void main() method in class
> extending Thread class,

In general, it's not a good idea to extend Thread. Just implement
Runnable instead.
Ryan Stewart - 05 Mar 2004 18:01 GMT
> > Hi,
> >
[quoted text clipped - 3 lines]
> In general, it's not a good idea to extend Thread. Just implement
> Runnable instead.

Why is that anyhow? If you have a simple task for the thread to run, why add
the extra step? Using Runnable feels clumsy, especially in naming the
variables. Say I want to use a thread to write from a message queue to a log
file or something along those lines:

MyLogger logger = new MyLogger(); // MyLogger implements Runnable
Thread loggerThread = new Thread(logger);
loggerThread.start();

Conceptually, what is "logger" and what is "loggerThread"? Why are they two
different things? Extending Thread seems much cleaner, so what's the reason
for not?
Eric Sosman - 05 Mar 2004 19:35 GMT
> > > Hi,
> > >
[quoted text clipped - 16 lines]
> different things? Extending Thread seems much cleaner, so what's the reason
> for not?

   Take a look at the implementation of MyLogger.  You
didn't show it, but my crystal ball tells me that MyLogger
is a subclass of Logger, that is, it specializes or extends
the more general or less powerful superclass.  Since a Java
class can have only one superclass, MyLogger cannot extend
both Logger and Thread.  So, how can you run a MyLogger in a
separate thread?  Java's answer:

    class MyLogger extends Logger implements Runnable

   Now all is good.  The relationship between MyLogger and
Logger is just as it would be if no threads were involved: a
MyLogger object "is a" Logger object, methods and fields are
inherited as per usual, and so on.  But at the same time, it's
simple to run a MyLogger instance in a separate thread, using
exactly the code you've shown.

   If there were no Runnable interface and extending Thread
were the only way to get parallel execution, it would still be
possible to do this sort of thing but in a clumsier fashion:

    class MyLogger extends Logger { ... }

    class MyParallelLogger extends Thread {
       private final MyLogger logger;
       MyParallelLogger(MyLogger logger) {
           this.logger = logger;
       }
       public void run() { ... }
    }

    MyParallelLogger mpl = new MyParallelLogger(new MyLogger());
    mpl.start();

Implementing Runnable is easier than jumping through this
silly hoop, I think.

Signature

Eric.Sosman@sun.com

Ryan Stewart - 07 Mar 2004 14:02 GMT
> > > > Hi,
> > > >
[quoted text clipped - 53 lines]
> Implementing Runnable is easier than jumping through this
> silly hoop, I think.

MyLogger is actually its own little thing, not extending anything, but I see
your point. I hadn't considered the inheritance issue before. Thanks for the
reply.
Steve Horsley - 05 Mar 2004 20:45 GMT
>>>Hi,
>>>
[quoted text clipped - 16 lines]
> different things? Extending Thread seems much cleaner, so what's the reason
> for not?

Many will argue that your LoggerThread is not logically a Thread any more
because its purpose has been changed. A Thread exists to run Runnables, thus
breathing life into an object. And it exists as a control-panel for a
thread (lower case) of execution within the program.

On the other hand, a LoggerThread is intended to do no such thing. You are
restricting its function, not extending it. To use a LoggerThread as a
Thread should be used (i.e. creating it round a Runnable) would be against
the design of LoggerThread. Different animals.

But I think the worst problem is the confusion it causes with beginners - the
original post to this thread being one of many examples in this ng. In multi-
threaded programs, having Threads call methods on other Threads (or their
derivatives) and the interactions between object monitors becomes very
confusing.

Steve
Ryan Stewart - 07 Mar 2004 14:25 GMT
> >>>Hi,
> >>>
[quoted text clipped - 34 lines]
>
> Steve
That makes sense. I can definitely see Thread being a consumer of Runnables.
However, Thread itself implements Runnable. It seems that its creators
intended it to be used this way. Maybe it should have been designed
differently.
Steve Horsley - 08 Mar 2004 22:55 GMT
> That makes sense. I can definitely see Thread being a consumer of Runnables.
> However, Thread itself implements Runnable. It seems that its creators
> intended it to be used this way. Maybe it should have been designed
> differently.

I wonder if there is some internal reason why Thread must be Runnable, but
I think the most likely thing is that we are looking back with the 20/20
vision of hindsight. I think designing an API must be an order of magnitude
harder than just learning to use it, as we mere mortals are doing.

Steve
FISH - 09 Mar 2004 12:15 GMT
[snipped...]
> Many will argue that your LoggerThread is not logically a Thread any more
> because its purpose has been changed. A Thread exists to run Runnables, thus
[quoted text clipped - 5 lines]
> Thread should be used (i.e. creating it round a Runnable) would be against
> the design of LoggerThread. Different animals.

Yes, but these more restrictive subclasses appear all the time in OO
programming.  Button extends Component in AWT, yet you cannot
(legitimately) use Button as a blank canvas like you can with
Component.

I agree, Thread gets overused (and I'm probably just as guilty as
anyone!)  Threading code should be looking to use Runnable most of the
time - but there are odd occassions when extending Thread makes more
sense, particularly when your class isn't a straight forward
start->run->stop type afair.

I think if you try to stick too tightly to rules like "every subclass
should be a more expressive version of its parent" then you can end up
backing yourself into a lot of corners.  The trick, of course, is to
know when to obey rules, and when it makes more sense to bend them.

> But I think the worst problem is the confusion it causes with beginners - the
> original post to this thread being one of many examples in this ng. In multi-
> threaded programs, having Threads call methods on other Threads (or their
> derivatives) and the interactions between object monitors becomes very
> confusing.

To be honest though, you will get that regardless of whether the class
itself is a Thread subclass, or simply a Runnable which defers all the
threading nitty-gritty.  Using Runnable is not, as far as I'm aware,
a silver bullet that makes interactions between threaded classes and
monitors etc. any easier.  Spagetti thread interactions are just as
bad
regardless of what construct you used to make the code threadable.

-FISH-   ><
Steve Horsley - 10 Mar 2004 00:25 GMT
> [snipped...]
>
[quoted text clipped - 13 lines]
> backing yourself into a lot of corners.  The trick, of course, is to
> know when to obey rules, and when it makes more sense to bend them.

Agreed.

>>But I think the worst problem is the confusion it causes with beginners - the
>>original post to this thread being one of many examples in this ng. In multi-
[quoted text clipped - 9 lines]
> bad
> regardless of what construct you used to make the code threadable.

I have to disagree here, purely on the basis of the number of beginners
I see posting here who are clearly having trouble keeping track of
what is happening when Thread A is calling Thread B's methods:- who's
instance variables are being used, and which object's monitor is being
locked. I think the fact that your objects are Thread subclasses really
does muddy the water. Yes I know it's simple when you get the hang of it,
we're talking about people who are struggling to get their heads round
both OO and multithreading at the same time.

Steve
Tony Morris - 06 Mar 2004 11:28 GMT
> > > Hi,
> > >
[quoted text clipped - 16 lines]
> different things? Extending Thread seems much cleaner, so what's the reason
> for not?

I concur with the other posts regarding Runnable/Thread.
It is more useful to provide the ability for a class to directly extend some
other class (other than java.lang.Object) if the need arises in the future
(granted, if this does occur, something is likely to be wrong with the
processes in place for design and implementation).

I'd also like to point out that, in practice, if I wrote a Runnable
implementation that was so trivial that determining a name for it is
frustrating, I usually don't bother naming it (by using an anonymous class).
This is a general observation, rather than a convention - that is, just
because a class name is not easily determined does not necessarily imply
that it is a good reason to use an anonymous class.

Signature

Tony Morris
(BInfTech, Cert 3 I.T., SCJP[1.4], SCJD)
Software Engineer
IBM Australia - Tivoli Security Software
(2003 VTR1000F)



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.