You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-users@xmlgraphics.apache.org by Andreas Junius <An...@sydac.com.au> on 2010/10/28 04:12:03 UTC

How to remove a JSVGComponent AND killing the threads created by it?

Hi everybody,

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? And most importantly: how can I
get rid of them? Any hints are highly appreciated!

Cheers,
	Andreas

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


Re: How to remove a JSVGComponent AND killing the threads created by it?

Posted by Helder Magalhães <he...@gmail.com>.
Hi Andreas,


> 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:

Overall, it looks good. Could you turn it into a patch and attach to
the relevant bug, please? (And add a link to that message/thread [1]
as well). Thanks! (If you are unable to/not interested in
contributing, at least confirm it so one can try to pick up from
here.) :-)


> I capitalised the constants:
[...]
> And introduced a control variable for the thread:
[...]
> 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:
> And one for the ReferenceQueue (which isn't actually a singleton):
[...]
> The CleanerThread-constructor should at least throw an exception if one tries to create more than one instance:
[...]
> The run method evaluates the control variable, which is only possible if we use the timeout facility of the remove method:
[...]
> And finally the exit method, which can be called to stop the CleanerThread:
[...]
> 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:
[...]

The reasoning is very coherent and sounds fine - I'd even invite you
to consider becoming an active contributor through being more active
in the mailing list and/or even pick up on a few open issues [2]...
;-)

@Other developers: what do you think about this? Overall, to me they
look good but I'm not enough into the details to properly estimate the
impact introduced by the these changes.


> Remains the question why Batik needs all this thread-stuff? Unfortunately I don't have the time to figure this out.

I guess this is already answered in the previously provided link: it
has to do with thread safety [3]. ;-)


> The solution above works fine for me.

Glad to hear you find your way! :-)


> Cheers,
>        Andreas

Thanks for sharing,
 Helder


[1] http://mail-archives.apache.org/mod_mbox/xmlgraphics-batik-users/201011.mbox/browser#msg-1
[2] https://issues.apache.org/bugzilla/buglist.cgi?query_format=specific&bug_status=__open__&product=Batik
[3] http://xmlgraphics.apache.org/batik/using/scripting/java.html#Threads

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


RE: How to remove a JSVGComponent AND killing the threads created by it?

Posted by Andreas Junius <An...@sydac.com.au>.
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.magalhaes@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-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org


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


Re: How to remove a JSVGComponent AND killing the threads created by it?

Posted by Helder Magalhães <he...@gmail.com>.
> 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-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org