How can an object send itself to a child?

  • Thread starter nooneinparticular314159
  • Start date
N

nooneinparticular314159

I want to allow a parent objects and its child to communicate.
Sending messages to the child is easy, since I can simply write to
that child's methods. But the child needs to send messages back to
the parent, and not necessarily when the parent is able to poll the
child. (In fact, almost certainly not when the parent is able to poll
the child.) How can I pass the parent to the child so that the child
can send messages back to the parent?

Also, if I do this, will I ever be able to garbage collect the
parent? At some point, I will want to eliminate the parent and its
children. But the child will have a reference to the parent, and the
parent will have a reference to the child. So will they ever get
marked for garbage collection?

Thanks!
 
P

Peter Duniho

I want to allow a parent objects and its child to communicate.
Sending messages to the child is easy, since I can simply write to
that child's methods. But the child needs to send messages back to
the parent, and not necessarily when the parent is able to poll the
child. (In fact, almost certainly not when the parent is able to poll
the child.) How can I pass the parent to the child so that the child
can send messages back to the parent?

IMHO, both the parent and the child should be implementing the "listener"
pattern that's common in Java, meaning that there's no polling. Instead,
both classes will implement some interface (which may be different for
parent and child) that defines the "listener" and then add itself as a
"listener" for the other class. Then the publisher class will call the
appropriate method for each listener that's added itself to that class's
listeners.

Java is full of examples of this pattern.
Also, if I do this, will I ever be able to garbage collect the
parent? At some point, I will want to eliminate the parent and its
children. But the child will have a reference to the parent, and the
parent will have a reference to the child. So will they ever get
marked for garbage collection?

As far as I know, they should. I'm not an expert in Java per se, but
typically a garbage collection system will have the idea of "rooted"
objects, and anything not reachable from a rooted object is eligible for
collection. So as long as the parent and child only have references to
each other, and nothing else refers to either of them, they would be
eligible for collection.

Circular references should not be a problem.

Pete
 
N

nooneinparticular314159

Ok. Let me rephrase the problem a little bit. The application is
expecting some data from the network. One object gets that data,
decodes it, and passes it on to a second object which decides what
action to take based on what was in the message. That second object
may need to tell the first object to write some data back out to the
network. To do so, it must put some data in the first object's
message queue, so that when it gets called, it will have data to write
out to the network. The first object will then immediately write the
data to the network and life will be good. The problem is that object
#2 must be able to reference object #1. If I implemented a listener
object of some sort, then that object would still have to reference
object #1 before object #1 itself is called by the main method.

Thanks!
 
L

Lew

Peter said:
As far as I know, they should. I'm not an expert in Java per se, but
typically a garbage collection system will have the idea of "rooted"
objects, and anything not reachable from a rooted object is eligible for
collection. So as long as the parent and child only have references to
each other, and nothing else refers to either of them, they would be
eligible for collection.

Circular references should not be a problem.

<http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf>
p. 8

One insight from this paper is that there really isn't just one "The" Garbage
Collector - there is a panoply of GC algorithms tuned for different tradeoffs
between speed, memory use, throughput, pause time and so on.

Looks like they'll all eliminate the circular-reference orphan system.
 
N

nooneinparticular314159

Ok. So so long as I delete some parent to the circular references,
the parent and the child will both be garbage collected correctly then?
 
P

Peter Duniho

[...] The problem is that object
#2 must be able to reference object #1. If I implemented a listener
object of some sort, then that object would still have to reference
object #1 before object #1 itself is called by the main method.

There's no "listener object". Your object #1 and object #2 _implement_ a
listener interface. They are the listeners, and they would each be added
(either by themselves or by whatever code creates the two objects) as a
listener to the other object.

Again, I recommend looking at the existing Java listener interfaces. Once
you understand those, you'll be better prepared to implement a similar
design yourself.

Pete
 
L

Lew

Ok. Let me rephrase the problem a little bit. The application is
expecting some data from the network. One object gets that data,
decodes it, and passes it on to a second object which decides what
action to take based on what was in the message. That second object
may need to tell the first object to write some data back out to the
network. To do so, it must put some data in the first object's
message queue, so that when it gets called, it will have data to write
out to the network. The first object will then immediately write the
data to the network and life will be good. The problem is that object
#2 must be able to reference object #1. If I implemented a listener
object of some sort, then that object would still have to reference
object #1 before object #1 itself is called by the main method.

package apack;

import bpack.B;
import bpack.BEvent;
import bpack.BListener; // declares handleBEvent( BEvent )

public class A implements BListener
{
public void run()
{
B b = new B();
b.addBListener( this );
b.run();
}

public void handleBEvent( BEvent event )
{
doSomethingUsefulBasedOn( event );
}
}
 
M

Mark Space

Ok. Let me rephrase the problem a little bit. The application is
expecting some data from the network. One object gets that data,
decodes it, and passes it on to a second object which decides what
action to take based on what was in the message. That second object
may need to tell the first object to write some data back out to the
network. To do so, it must put some data in the first object's
message queue, so that when it gets called, it will have data to write
out to the network. The first object will then immediately write the
data to the network and life will be good. The problem is that object

Well, I'd consider making separate Input and Output objects.
Considering that managing queues is pretty complicated in itself, I
don't see any reason to make your single parent object "double up" on
it's work load and do both.

That will also simplify your IO, I think, but "decomposition into
smaller chunks" is the main goal.
#2 must be able to reference object #1. If I implemented a listener
object of some sort, then that object would still have to reference
object #1 before object #1 itself is called by the main method.

Right. As Lew implied, initialize your objects first. Get all those
pointers established. Then, kick off the IO process and open the
port/file/stream/etc.
 
L

Lew

Mark said:
initialize your objects first. Get all those
pointers established. Then, kick off the IO process and open the
port/file/stream/etc.

In general, excellent advice. In particular, it's dangerous to invoke
overridable methods from within a constructor.

The simple example I posted does not check to guarantee that the Listener is
set before a B.run() happens. There are patterns that let you do that, just
as there are patterns to add Listeners to objects that are already running.
The simple example also does not rely on multi-threaded execution, but could
expand to do so. Callbacks work in single-threaded patterns, too.

These patterns share a commitment to the clean separation of construction from
initialization from action to which Mark alluded.
 

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,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top