Hi Helder,

Thanks for your reply! I've been finally able to fix the problem. However I 
don't think that the patch provided on Bugzilla works. Therefore here my 
changes on the CleanerThread class for anyone interested:

I capitalised the constants:

  private static volatile ReferenceQueue QUEUE_INSTANCE = null;

  private static volatile CleanerThread THREAD_INSTANCE = null;

And introduced a control variable for the thread:

  private volatile boolean alive = false;


A static access method for the singleton implementation of the CleanerThread. 
Please note that the user Archie Cobbs is right with his estimation, that the 
existing method isn't thread safe (although the suggested double check lock 
won't work). I got several instances of CleanerThreads with the existing code:

 /**
   * Returns CleanerThread singleton instance
   * 
   * @return instance
   */
  public static synchronized CleanerThread getInstance()
  {

    if (THREAD_INSTANCE == null)
    {
      try
      {
        THREAD_INSTANCE = new CleanerThread();
      }
      catch (IllegalAccessException e)
      {
        // should not happen here
        e.printStackTrace();
      }

    }
    return THREAD_INSTANCE;
  }



And one for the ReferenceQueue (which isn't actually a singleton):

  public static synchronized ReferenceQueue getReferenceQueue()
  {

    if (QUEUE_INSTANCE == null)
    {
      QUEUE_INSTANCE = new ReferenceQueue();
      THREAD_INSTANCE = getInstance(); // it seems, that queue implies
                                       // cleanerthread?
    }

    return QUEUE_INSTANCE;
  }



The CleanerThread-constructor should at least throw an exception if one tries 
to create more than one instance:

private CleanerThread() throws IllegalAccessException
  {
    super("Batik CleanerThread");
    if (THREAD_INSTANCE != null)
    {
      throw new IllegalAccessException("Batik CleanerThread-instance already 
created.");
    }
    setDaemon(true);
    this.alive = true;
    start();
  }



The run method evaluates the control variable, which is only possible if we use 
the timeout facility of the remove method:

public void run()
  {
    Reference<?> ref = null;
    while (this.alive)
    {
      try
      {
        if (getReferenceQueue() != null && (ref = 
getReferenceQueue().remove(250)) != null)
        {
          if (ref instanceof ReferenceCleared)
          {
            ((ReferenceCleared)ref).cleared();
          }
        }
      }
      catch (InterruptedException e)
      {
        QUEUE_INSTANCE = null;
        THREAD_INSTANCE = null;
        this.alive = false;
        Thread.interrupted(); // restore interruption status
      }
    }
  }


And finally the exit method, which can be called to stop the CleanerThread:

public void exit() {
    this.alive = false;
    this.interrupt();
    CleanerThread.QUEUE_INSTANCE = null;
    CleanerThread.THREAD_INSTANCE = null;
  }



I identified furthermore the UpdateManager as a source of these 
RunnableQueue-nn and Timer-nn threads. A call to interrupt stops these threads, 
maybe its somewhere documented, but I couldn't find it:

UpdateManager um = yourSVGComp.getUpdateManager();
    if (um != null && um.isRunning())
    {
      um.interrupt();
    }


Remains the question why Batik needs all this thread-stuff? Unfortunately I 
don't have the time to figure this out. The solution above works fine for me.

Cheers,
        Andreas



http://java.sun.com/developer/technicalArticles/Programming/singletons/
http://www.ibm.com/developerworks/java/library/j-dcl.html
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html















-----Original Message-----
From: Helder Magalhães [mailto:helder.magalh...@gmail.com] 
Sent: Saturday, 30 October 2010 6:19 PM
To: batik-users@xmlgraphics.apache.org
Subject: Re: How to remove a JSVGComponent AND killing the threads created by 
it?

> Hi everybody,

Hi Andreas,


> I created a GUI using several instances of the batik JSVGComponent. 
> Some of these components gets removed after a while, e.g. dialogues. 
> Though each comnponent creates some threads, called RunnableQueue-nn 
> and Timer-nn.
> Where are these threads created and why?

Actually, there's plenty of good documentation available (IMO, without being 
too lengthy and boring, Batik documentation is one of the best I've seen in OSS 
projects). You may be interested in taking a look at scripting with Java [1] 
(that's what's probably happening "under the hood". :-)


> And most importantly: how can I
> get rid of them?

A quick look at open bugs [2] (note that several were fixed since Batik 1.7 - 
they relate with the trunk SVN version) showed bug 48771 [3] as the potential 
guilty. You could help by testing that patch and add your results to the bug 
report [3]. Thanks! ;-)


> Any hints are highly appreciated!
>
> Cheers,
>        Andreas

Hope this helps,
 Helder


[1] http://xmlgraphics.apache.org/batik/using/scripting/java.html
[2] 
https://issues.apache.org/bugzilla/buglist.cgi?query_format=specific&bug_status=__open__&product=Batik
[3] https://issues.apache.org/bugzilla/show_bug.cgi?id=48771

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscr...@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-h...@xmlgraphics.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscr...@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-h...@xmlgraphics.apache.org

Reply via email to