Win a copy of Getting started with Java on the Raspberry Pi this week in the Raspberry Pi forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Tim Cooke
  • Jeanne Boyarsky
Sheriffs:
  • Rob Spoor
  • Devaka Cooray
  • Liutauras Vilda
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Piet Souris

Creating multiple children threads

 
Ranch Hand
Posts: 443
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
How do you create multilple children threads if you use the "extend the Thread class" approach rather than "implementing Runnable"?
Example:

Thanks.
 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Simply create more than one instance of the class that extends thread, like this:
 
Alton Hernandez
Ranch Hand
Posts: 443
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[/qb]<hr></blockquote>
But the result is you have 2 main threads and 2 children threads. One main threads does not see what the other is doing. They don't even share the same instance variable.
Isn't it?
I wanted to implement the same code by extending the Thread class instead of implementing Runnable.

[ July 02, 2003: Message edited by: Alton Hernandez ]
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, as they're separate objects, they won't share the same instance variables. If you want to threads to share the same variable, you'll have to use the method of creating a class that implements the Runnable interface and pass a reference to the same object to each of the new threads, like this:

Of course, if you have multiple threads sharing a single variable, you'll may have to worry about mutual exclusion of that variable.
I hope that helps,
Corey
 
Alton Hernandez
Ranch Hand
Posts: 443
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So can I say then that if you want to spawn more than one thread from an object, you have to implement the Runnable interface?
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, not necessarily. There is nothing stopping you from doing something like this:

You are extending Thread so there's no reason you couldn't do something like this. I'm sorry if my first response made it sound like you couldn't do this - the example I showed was just easier using the Runnable interface.
I hope this helps,
Corey
 
Alton Hernandez
Ranch Hand
Posts: 443
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Corey,
Thank you for that sample code.
However, I still find that it is not the same thing. There are still two instances whereas my previous sample has only one.
I modified your code to make it more clearly:

I added those that are in bold.
The two threads created in 1 and 2 will enter the method m1() at the same time even though that method is synchronized. The reason being is that there are two objects therefore there are two locks. So the 2 threads are not really competing for a lock.
Compare that with my previous sample of using Runnable. There is only one object and therefore only 1 lock to compete for.
 
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you want two new threads, you *must* create two new Thread objects. Every thread has its own Thread object to manage that thread.
A th1 = new A();
A th2 = new A();
If you want those threads to access on the same object data, I suppose you will have to give them the same object.

java.lang.ThreadGroup[name=main,maxpri=10]
Thread[main,5,main]
Thread[Thread-0,5,main]
Thread[TH-1,5,main]
Thread[TH-2,5,main]
TH-1
TH-2
 
Alton Hernandez
Ranch Hand
Posts: 443
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Marlene Miller:
If you want two new threads, you *must* create two new Thread objects. Every thread has its own Thread object to manage that thread.
A th1 = new A();
A th2 = new A();


But this like having 2 instances where each instance has a child thread. So if your synchronized method is inside this object, each thread will not lock the other because there are 2 locks.
Unlike if you implement the Runnable interface, you can have only one instance with 2 child threads.
Compare the following codes:
Implementing Runnable:


By extending Thread:
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Don't let yourself be caught up by syntax, Alton. What we're really looking at are two similar ways to accomplish the same sort of task. In your example, you have one case in which you implement runnable and then synchronize a method to mutually exclude any threads trying to run that method. This works great because the method that you're synchronizing is found within the Runnable class that you're instantiating and passing to the two threads. Note that, even when you're using the Runnable method, you still have two distinct objects and one shared object for them to both act upon.
When you don't use the Runnable method, if you go back to my example, you still have two threads and one shared object. The problem here is that if you attach the keyword synchronized to a method, you won't get the mutual exclusion you're after because the synchronization is now occurring on two separate objects which, of course, have two separate locks. However, if you modify the syntax slightly so that the two threads lock on the shared object (which is what we were doing in the first example), the mutual exclusion works just fine. Take a look at this example:

I hope that helps, Alton.
Corey
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When a thread executes an instance method, the thread stack has a pointer(*) to some object data on the heap. The thread stack has the local variables.

When two threads execute the same instance method, their thread stacks may point to the same object data OR to different object data on the heap. Each thread stack always has its own copy of local variables.

When a thread executes a method of its own class or subclass, the thread stack is pointing to the Thread object. Each thread stack points to its own Thread object.
When a thread executes a method of a Runnable object, the thread stack is pointing to the Runnable object on the heap.
If you want two threads to point to the same object on the heap while executing a method, you have to give them that object and then you invoke the method on that object. You can give both of them the same Runnable object. Or you can give both of them some other object.
(*) leaving out some details here
[ July 03, 2003: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
These threads acquire the lock of the same object.

[ July 03, 2003: Message edited by: Marlene Miller ]
 
Alton Hernandez
Ranch Hand
Posts: 443
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Corey and Marlene.
I think I finally figured out what is it that I am confused about.
Threads are lightweigth processes which means that they share memory space. I believe in Java, this shared memory space is called main memory. This main memory contains instance variables, class variables, etc. Java threads also has its own private memory space that other threads cannot see. This may contain local variables, working copies of the instance variables, etc.
When I look at threads started by objects that extend the Thread class, I don't see any shared memory. If it is thru the implementation of Runnable, it looks like it has. But looking closer, both don't seem to have shared memory (IMHO). It appears that threads don't have access to their parent's instance variables, and they cannot share data. What appears to be a shared memory is actually just giving each thread a pointer to the same object (much like passing the same reference to 2 different objects). The threads can work on that same object, synchronized in that object, and signal each other, but not share data, specially those of its parent. So for example, the parent thread opens a file, and then creates 2 threads that will read/write on that file, it has to explicitly pass that file object to the 2 threads. Those 2 threads cannot just grab it from the parents memory.
When I picture Java threads in my head, I used to picture them like this:

Now, I think that the right picture should be like this, which explains why even when the parent ends, the other threads(its children) continue on.

Anyway, this is what I think. Any comments?
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Alton. Thank you for telling us how you were thinking and what was not making sense to you. Interesting.
I am happy to know you figured it out. What you have said is accurate as far as I know.
[ July 05, 2003: Message edited by: Marlene Miller ]
 
Author and all-around good cowpoke
Posts: 13078
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think the term "children" is misleading you. Threads don't have a parent-child relationship.
The only family a Thread has is a ThreadGroup.
Bill
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi
warning the following is out of exam scope warning but it helps a lot!
I believe that Marlene post has confused Alton.


When a thread executes an instance method, the thread stack has a pointer(*) to some object data on the heap.


This is the hidden argument this, the object on which the method was invoked. A "pointer" to it is stored in the first local variable (index 0)
I suspect that Alton thought this object was the only "shared" memory between threads. In fact all objects whose references are visible and accessible for the thread will be at its disposal.


So for example, the parent thread opens a file, and then creates 2 threads that will read/write on that file, it has to explicitly pass that file object to the 2 threads. Those 2 threads cannot just grab it from the parents memory.


Alton you are thinking in C , but you should think in Java. The variables from the "parent" thread are not "passed" to the "child" thread. Think only whether they are local, private, inherited etc.
These simplified descriptions may help:
A thread of execution (in Java) is a counter of program and a Java stack executing a series of method calls. For each method call a new frame is added. There go the local variables of the method and the arguments passed to it. The references to objects are private to the thread unless you give them up outside the method, or copys are kept for the arguments. Threads can access data outside as long as their references are visible and accessible. For synchronizing several threads, the same lock should be used. But this lock is not the only "shared" data among the threads.
A Thread object provides both the job for the thread and a way to manage the thread of execution, starting it, synchronizing etc.
A Runnable object only provides the job for the thread, but it does so in a way that can be more convenient than a thread object does.
 
Alton Hernandez
Ranch Hand
Posts: 443
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,
Thanks everyone.

Originally posted by Jose Botella:

Alton you are thinking in C , but you should think in Java.


Yes, that is true. I was thinking along the line of POSIX thread.
 
Look ma! I'm selling my stuff!
Low Tech Laboratory
https://www.kickstarter.com/projects/paulwheaton/low-tech-0
reply
    Bookmark Topic Watch Topic
  • New Topic