The situation:

In my program, there are a list of cues. To call a cue at a certain time, there are objects called Triggers. Cues have many public methods that allow them, among other things, to be "fired" (which causes them to perform an action). Triggers "fire" cues when they are activated. They do this by taking a reference to the Cue and then calling Cue.fire(). The triggers are all stored in a class called TriggerManager which keeps them in an array list. Cues are part of a linked list with eachother. So, in summery: Triggers know about Cues, but Cues don't know about triggers; Triggers call cues at certain times.

The problem:

When I remove a Cue from the linked list, it's still "alive"/hasn't been garbage collected because there's a Trigger with a reference to it. The natural thing would be to delete the Trigger, but that creates a host of issues that need to be solved:

The main one is this: Since, the Cue doesn't know about the Trigger that references it, how do I get it to be deleted. (Especially since its referenced by a TriggerManager class). There has to be a way to do this without making Cues dependent on Triggers and Triggers dependent on their TriggerManagers OR Cues dependent on TriggerManagers, which should have nothing to do with Cues (Giving everything a bidirectional reference to each other will make the code complicated and hard to keep track of)

Question: Is there a solution that will fix my problem while keeping the code manageable? Is my design inherently flawed? If so, how do I fix it?

  • 1
    Perhaps you might want to use a WeakReference? docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/… Jun 6, 2013 at 23:24
  • @ThomasEding That seems like a good idea. The only problem is that there will still be the wasted space taken up by the Trigger object. It would be helpful if there was a way to delete the Trigger at the same time that the Cue is deleted.
    – sinθ
    Jun 7, 2013 at 1:21

2 Answers 2


The linked list isn't really helping you here. Replace it with a CueManager that

  1. Contains the list of Cues
  2. Maps the Cues to their respective Triggers

The CueManager should then control the life-cycle of the Cues--adding them and removing them from their respective triggers.

interface CueManager {
  public addCueToTrigger(Cue, Trigger);
  public removeCueFromTrigger(Cue, Trigger);
  public deleteCue(Cue);
  • Thanks, but removing the linked list isn't possible. I only really explained part of my program (the part that deals with the Triggers), but the linked list is actually one of the most important parts of the program in general.
    – sinθ
    Jun 6, 2013 at 22:24
  • 1
    Okay, keep the list separate then, but use a CueManager to manage their life-cycle anyway. If the idea is keep the Cues decoupled from the Triggers, you need to use indirection to manage it. Jun 7, 2013 at 3:18

My first thought was some sort of publish/subscribe model and/or callbacks, but that violates your requirement to avoid bidirectional references.

An alternative might be to add a "cueIsAlive" flag to the Cue. Set it to true in the constructor, have the RemoveFromLinkedList() call set it to false, and use it in your Cue.Fire() method:

public void Fire() {
    if (this.cueIsAlive) {
        ... execute Fire code ...

I'm not sure if this would be considered a zombie object or not - the basic idea is to make it harmless until such time that it can be garbage collected.

  • 1
    It does make the objects a kind of zombie objects (IMHO), by explicitly defining a zombie-like state. If you can guarantee that the reference through Trigger will eventually be removed, this is not necessarily a bad thing. Jun 7, 2013 at 7:09
  • I'm not sure how Java events work, but in ActionScript (which is similar), the Cue could dispatch an event when it becomes inactive and Trigger could then release it. Under the hood, adding an event listener does add a reference to the callback, but this doesn't create an explicit dependency between the two Classes. Jun 9, 2013 at 21:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.