Re: Why can't I start a thread twice?

Discussion in 'Java' started by Lew, May 2, 2009.

  1. Lew

    Lew Guest

    Chuan C. wrote:
    > When I try to start the run() method of a subclass of Thread for
    > a second time I get this runtime error:
    >
    > Exception in thread "AWT-EventQueue-1"
    > java.lang.IllegalThreadStateException
    > at java.lang.Thread.start(Thread.java:595)


    Peter answered your primary question, so I'm going to point out some things
    unrelated to that question.

    > This is what I do:
    >
    > class X extends Thread {


    It is usually better to implement 'Runnable' and pass it to a 'Thread' than to
    extend 'Thread'.

    Not much better, but better.

    > Boolean go;


    Why did you choose 'Boolean' instead of 'boolean'?

    If the variable were 'boolean' it would be initialized to 'false' for you
    automatically.

    You can also initialize it directly in the declaration, so you wouldn't need
    to do it in the constructor body (or even declare a constructor at all, perhaps).

    boolean go = false;

    Also, why did you choose package-private (i.e., default) access for the
    variable instead of private access?

    > public X() {
    > go = false;
    > }
    >
    > public void run() {
    > go = true;
    > for (int n = 0; n < 100 && go; n++) {
    > // various activities
    > }
    > }
    > }
    >
    > The calling program does:
    > b = new X();
    > b.start();
    > b.go = false; -> works OK


    Perhaps this is why 'go' is package-private. This line would fail if the
    calling program were in a different package from the 'X' class.

    A better idiom is to declare the variable 'private' and use public accessor
    and mutator methods (a "getter" and a "setter") to manipulate the variable.

    > b.start(); <- the runtime error above
    >
    > Am I not supposed to repeat a thread this way?


    There are a number of excellent books and articles on threaded programming in
    Java. Look for authors Brian Goetz, Doug Lea and Joshua Bloch. /Java
    Concurrency in Practice/, by Brian Goetz, Messrs. Lea and Bloch and others, is
    an excellent book on the subject. Bloch's /Effective Java/ touches on the
    matter as well, and is essential reading for all Java programmers. Brian
    Goetz also has multiple articles published on IBM's DeveloperWorks site that
    deal with multi-threaded programming. The Sun Java tutorial touches on it as
    well.

    <http://www.ibm.com/developerworks/search/searchResults.jsp?searchType=1&searchSite=dW&searchScope=javaZ&query=Brian+Goetz&Search=Search>

    --
    Lew
    Lew, May 2, 2009
    #1
    1. Advertising

  2. Lew wrote:
    > It is usually better to implement 'Runnable' and pass it to a 'Thread'
    > than to extend 'Thread'.
    >
    > Not much better, but better.


    The general recommendation is to implement the interface instead of
    extending the class unless you have a reason not to do so. If nothing
    else, it makes your life easier if you decide that the class needs to
    extend something else for other reasons.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, May 2, 2009
    #2
    1. Advertising

  3. Chuan C. wrote:
    > Lew
    > Lew wrote:
    >> Chuan C. wrote:
    >>> This is what I do:
    >>>
    >>> class X extends Thread {

    >> It is usually better to implement 'Runnable' and pass it to a 'Thread'
    >> than to extend 'Thread'.

    >
    > It is about introducing Threads. This particular excercise is to be
    > solved this way.
    >
    >> Not much better, but better.
    >>

    > Why?


    "implements Runnable" allows the class to extend another class
    while "extends Thread" does not.

    If you are confident that you class will not need to extend
    another class later, then you don't care.

    >>> Boolean go;

    >> Why did you choose 'Boolean' instead of 'boolean'?

    >
    > Sorry, that was a typo.


    Be careful.

    >> If the variable were 'boolean' it would be initialized to 'false' for
    >> you automatically.

    >
    > This a habbit from other languages, where it is a not a good idea to
    > depend on default values. Is there concense in Java that numerical
    > types will be initialized to zero?


    Yes (for instance and class members - and for local variables the
    compiler will bother you for missing initializations).

    Arne
    Arne Vajhøj, May 2, 2009
    #3
  4. Chuan C. wrote:
    > Lew wrote:
    >> If the variable were 'boolean' it would be initialized to 'false' for
    >> you automatically.

    >
    > This a habbit from other languages, where it is a not a good idea to
    > depend on default values. Is there concense in Java that numerical
    > types will be initialized to zero?


    Everything except local variables is initialized to default types, which
    is roughly the type's equivalent of `0' (0 for integral types, null for
    reference types, and false for the boolean type). Local variables must
    be assigned before being used.

    Generally, the most common time people rely on default values is array
    initialization; otherwise, it's up to the style guide you rely on.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, May 2, 2009
    #4
  5. Lew

    Lew Guest

    Chuan C. wrote:
    > Lew
    >
    > Lew wrote:
    >> Chuan C. wrote:
    >>
    >>> This is what I do:
    >>>
    >>> class X extends Thread {

    >> It is usually better to implement 'Runnable' and pass it to a 'Thread'
    >> than to extend 'Thread'.

    >
    > It is about introducing Threads. This particular excercise is to be
    > solved this way.
    >
    >> Not much better, but better.
    >>

    > Why?
    >
    >>> Boolean go;

    >> Why did you choose 'Boolean' instead of 'boolean'?

    >
    > Sorry, that was a typo.
    >
    >> If the variable were 'boolean' it would be initialized to 'false' for
    >> you automatically.

    >
    > This a habbit from other languages, where it is a not a good idea to
    > depend on default values. Is there concense in Java that numerical
    > types will be initialized to zero?


    It's part of the very definition of the Java language that instance and static
    variables will be initialized to their default values (false, 0, '\u0000', 0L,
    0.0F, 0.0 or null depending on type), but that local variables will not be.
    There is a subtlety involving 'final' fields, which require an explicit
    assignment.

    From the Java Language Specification (JLS):
    <http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.12.5>

    --
    Lew
    Lew, May 2, 2009
    #5
  6. Lew

    Lew Guest

    Joshua Cranmer wrote:
    > Chuan C. wrote:
    >> Lew wrote:
    >>> If the variable were 'boolean' it would be initialized to 'false' for
    >>> you automatically.

    >>
    >> This a habbit from other languages, where it is a not a good idea to
    >> depend on default values. Is there concense in Java that numerical
    >> types will be initialized to zero?

    >
    > Everything except local variables is initialized to default types, which
    > is roughly the type's equivalent of `0' (0 for integral types, null for
    > reference types, and false for the boolean type). Local variables must
    > be assigned before being used.
    >
    > Generally, the most common time people rely on default values is array
    > initialization; otherwise, it's up to the style guide you rely on.


    With the caveat that explicit initialization of class or instance variables to
    their defaults assigns the same value twice.

    --
    Lew
    Lew, May 3, 2009
    #6
  7. Peter Duniho wrote:
    > On Sat, 02 May 2009 14:59:37 -0700, Arne Vajhøj <> wrote:
    >
    >> [...]
    >>>> It is usually better to implement 'Runnable' and pass it to a 'Thread'
    >>>> than to extend 'Thread'.
    >>>>
    >>>> Not much better, but better.
    >>>>
    >>> Why?

    >>
    >> "implements Runnable" allows the class to extend another class
    >> while "extends Thread" does not.
    >>
    >> If you are confident that you class will not need to extend
    >> another class later, then you don't care.

    >
    > Though, whether a person "cares" depends on certain preferences. It's
    > true that if you're sure the class won't need to extend another class,
    > there is no quantifiable reason to prefer one or the other. However, as
    > a personal preference, I prefer to only inherit a class if there's
    > actually a specific positive reason in favor of that. That "specific
    > positive reasons" is almost always about inheriting implementation, and
    > in the case of the Thread class, there's not really anything in the
    > implementation that needs inheriting. You can use the Thread class
    > as-is without further complication and with equivalent facility even
    > without inheriting from it.


    You can get Thread to execute any Runnable, but the code is cleaner
    to just instantiate and call start.

    > Some might consider this a corallary to the general OOP rule of thumb,
    > "prefer composition to inheritance". Inheritance is a very strong
    > contract, and should be done only when there is a clear "is a"
    > relationship between the base and derived class.


    But in the case of threads there is a "is a" relationship.

    > In addition to all that, I'll point out that you can "implement
    > 'Runnable'" simply by providing an anonymous class. In many cases, this
    > is as simple as this:
    >
    > Thread thread = new Thread(
    > new Runnable()
    > {
    > public void run()
    > {
    > threadMethod();
    > }
    > });
    >
    > Where "threadMethod()" is a method defined in the current class
    > containing the actual code for the thread.


    It is possible, but I don't like it. It does not separate what is
    in which thread very well.

    Arne
    Arne Vajhøj, May 3, 2009
    #7
  8. Lew

    BrianGoetz Guest

    The rule is pretty simple: the abstraction for "task" is Runnable, not
    Thread; the abstraction for "worker" is Thread.

    So, if you are implementing a *task* (which is almost always the
    case), implement it as a Runnable. If you are implementing a task-
    management framework (and why would you, when JUC provides an
    excellent one), only then is it reasonable to extend Thread.

    The confusion comes around from the notion that when you are writing a
    toy sample program, Thread seems more convenient for illustrating what
    is going on (e.g., there's a "writer thread" and a "reader thread"),
    so many examples
    in books use that approach -- and that colors the student's
    thinking.

    > >>>> It is usually better to implement 'Runnable' and pass it to a 'Thread'
    > >>>> than to extend 'Thread'.

    >
    > >>>> Not much better, but better.

    >
    > >>> Why?

    >
    > >> "implements Runnable" allows the class to extend another class
    > >> while "extends Thread" does not.

    >
    > >> If you are confident that you class will not need to extend
    > >> another class later, then you don't care.

    >
    > > Though, whether a person "cares" depends on certain preferences.  It's
    > > true that if you're sure the class won't need to extend another class,
    > > there is no quantifiable reason to prefer one or the other.  However, as
    > > a personal preference, I prefer to only inherit a class if there's
    > > actually a specific positive reason in favor of that.  That "specific
    > > positive reasons" is almost always about inheriting implementation, and
    > > in the case of the Thread class, there's not really anything in the
    > > implementation that needs inheriting.  You can use the Thread class
    > > as-is without further complication and with equivalent facility even
    > > without inheriting from it.

    >
    > OK, this point was known to me (I expected a technical difference).
    > In this particular simple example, my class is free to inherit Thread
    > or implement Interface. In matter of taste, I was also told to use
    > inheritance, only if there is an is-relationship between the two
    > classes. In my view, since my class needs a to run something in
    > paralled does not make it a _Thread_. It is still a moving object
    > for example. Any way, it looks like even the expers differ on this
    > matter.
    >
    > > In addition to all that, I'll point out that you can "implement
    > > 'Runnable'" simply by providing an anonymous class.  In many cases, this
    > > is as simple as this:

    >
    > >     Thread thread = new Thread(
    > >         new Runnable()
    > >         {
    > >             public void run()
    > >             {
    > >                 threadMethod();
    > >             }
    > >         });

    >
    > > Where "threadMethod()" is a method defined in the current class
    > > containing the actual code for the thread.

    >
    > That is too much for the introductory level we have. Thanks for
    > the hint anyway.
    >
    > Cya
    > Chuan.- Hide quoted text -
    >
    > - Show quoted text -
    BrianGoetz, May 3, 2009
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Enigma Curry
    Replies:
    1
    Views:
    486
    Peter Hansen
    Mar 15, 2006
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    877
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,805
    Smokey Grindel
    Dec 2, 2006
  4. Kiuhnm

    twice(twice(x))

    Kiuhnm, Apr 1, 2006, in forum: C++
    Replies:
    2
    Views:
    393
    Kiuhnm
    Apr 1, 2006
  5. Replies:
    5
    Views:
    1,605
    Roedy Green
    Jun 20, 2008
Loading...

Share This Page