You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:26:17 UTC

[sling-org-apache-sling-commons-threads] annotated tag org.apache.sling.commons.threads-3.2.2 created (now 4f77138)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git.


      at 4f77138  (tag)
 tagging 96e1f5e8c85f37cb8bf82820a900fbb276949020 (commit)
      by Julian Sedding
      on Thu Nov 26 16:45:09 2015 +0000

- Log -----------------------------------------------------------------
org.apache.sling.commons.threads-3.2.2
-----------------------------------------------------------------------

This annotated tag includes the following new commits:

     new cdf4581  Add new threads module for providing thread pools.
     new c3a54e0  Set svn:ignore
     new 6569a93  Use thread pool to create new threads instead of directly instantiating threads.
     new a216040  Create own thread pool for eventing.
     new 5dfc716  Use thread pooling for scheduler as well. Create own pool for eventing.
     new f8c7fb7  Use jvm default thread factory and always provide priority and daemon settings.
     new a5761c4  Use thread pool configuration object to be extensible.
     new b9020b0  Move licence and notice to top level dir.
     new e413af3  Add incubator disclaimer.
     new 1597daa  Add notice files.
     new 3020eb2  Write first element in pom in one line (to avoid problems with the maven release plugin) and minor pom fixes.
     new 2c687bd  Update notice files.
     new 4c666b9  SLING-417: Move sling/threads to commons/threads
     new 8d1f9f1  SLING-417: Move threads to commons.
     new 23e3268  Eclude maven-eclipse.xml generated by the maven eclipse plugin.
     new 5fa8b5a  SLING-442: Clean up exports, imports, dependencies and used plugins.
     new f7b228d  SLING-479 Fix @scr.tags:   - normalize metadata attribute settings to "no"   - ensure proper metadata and ds attributes are set   - create metatype.properties files where required   - fix metatype.properties files
     new b8442a7  SLING-483: Add excludes for javadocs (WiP)
     new f31810f  SLING-495 - NOTICE files generated using mknotice script
     new 7a30ca2  SLING-495 - NOTICE files updated according to changes in revision 662927
     new fc95c64  SLING-495 - NOTICE files regenerated with revision 663097 changes
     new 601db57  Use released version of parent pom.
     new e4986f9  [maven-release-plugin] prepare release org.apache.sling.commons.threads-2.0.0-incubator
     new 7097543  [maven-release-plugin] prepare for next development iteration
     new bac4721  Fix reference to parent pom.
     new 88286dd  SLING-521: Restore more notice files.
     new dc0cc02  SLING-521: Separate between notice files for bin and src dists.
     new 82242fd  SLING-521: Separate between notice files for bin and src dists.
     new 64c2458  SLING-521: Separate between notice files for bin and src dists.
     new b29c28c  Change copyright year to 2008.
     new 88db633  Update to released versions.
     new 3aaff93  [maven-release-plugin] prepare release org.apache.sling.commons.threads-2.0.2-incubator
     new c5e1a11  [maven-release-plugin] prepare for next development iteration
     new bac3bfb  Use latest snapshots again to make project buildable.
     new 0720836  Use released parent pom where possible.
     new bb289e6  SLING-555 : Update all poms to use the latest parent pom; update parent pom to include the incubator repo for plugins and use latest plugins.
     new daee250  SLING-758 : Correctly evaluate block policy and use the correct handler.
     new 194ca0d  Add more logging to easier detect pool problems.
     new 21e9144  SLING-808 : Increase version to 5-incubator-SNAPSHOT
     new 3ad9b97  Update notice files to include 2009 in copyright statement.
     new 58081a1  SLING-829 Cosmetics to the bundle/project names
     new 3a9b17c  SLING-865 : Move to bundles
     new ae528ef  SLING-865 : Adjust reactor pom and svn information in each module.
     new 6807294  SLING-865 : Adjust path to parent pom and add profiles for samples and contrib
     new 7807d1c  Use release parent pom
     new 03fc7dc  [maven-release-plugin] prepare release org.apache.sling.commons.threads-2.0.4-incubator
     new a28c935  [maven-release-plugin] prepare for next development iteration
     new 4ca55b3  Use next dev version of parent pom
     new bed1b63  Set parent pom to released version.
     new 6ad9afb  Move Sling to new TLP location
     new 10df9b4  SLING-1011 : Remove disclaimer file.
     new ae744d2  SLING-1011 : Adjust svn location
     new 97b3488  SLING-1011 : Remove disclaimer from readme's, adjust links to webite, fix versions in poms.
     new 97733b6  SLING-1033 Upgrade to Sling parent POM 6 (and ensure web app has the leglize stuff, too)
     new ca64268  SLING-1205 Upgrade all projects to parent POM 8 and use OSGi provided OSGi libraries
     new 3423042  SLING-1244 : Redesign thread pool management
     new 1be56f6  [maven-release-plugin] prepare release org.apache.sling.commons.threads-3.0.0
     new d87e5e7  [maven-release-plugin] prepare for next development iteration
     new b56bac2  Add some more debug information.
     new 60be200  Fix typo
     new c65358b  Use released parent pom.
     new 8145a6d  SLING-1699 : New default configuration is created on each startup
     new 7ec685e  Update notice files
     new f0b3a2a  [maven-release-plugin] prepare release org.apache.sling.commons.threads-3.0.2
     new 77bf590  [maven-release-plugin] prepare for next development iteration
     new 33781d0  SLING-1819 : Unused custom thread pool is never removed
     new 540bc62  SLING-1820 : Display current pool statistics in web console
     new b92d2c5  SLING-1821 :  Custom thread pools should get an optional label
     new 6d5d355  Add a web console label
     new 9499566  SLING-1833 : Remove direct dependency to web console by using new configuration printer support
     new 358040b  Prepare for release.
     new b6b8506  [maven-release-plugin] prepare release org.apache.sling.commons.threads-3.1.0
     new 327ebb0  [maven-release-plugin] prepare for next development iteration
     new 8046561  updating all modules to parent 10-SNAPSHOT in anticipation of emma additions to parent
     new c36972c  Update to recent snapshots
     new 0e4133b  Use latest releases.
     new 8ac6fdc  SLING-2150 : Update plugins to use the latest available versions
     new abc3e4c  Update to recent snapshot
     new c88d147  Using latest released parent pom
     new e281787  SLING-2187 - adding new module to contain our custom notice file; adding remote-resources plugin configuration to parent pom and removing all existing appended-resources NOTICE files
     new b7d45cc  temporarily using snapshots during release vote
     new 558c2bb  using latest releases
     new 22cbbc7  SLING-2480 : Add config for maven-sling-plugin to m2e configuration
     new bbd4453  Update to latest parent pom
     new ec3dff0  Use released versions
     new 6a7b2e4  Typo
     new 540daa4  SLING-2540 : Allow the ThreadPool to process Callable/Runnable and return a Future. Apply patch from Timothee Maret
     new 66cfaea  SLING-2563 - auto generate label based on a stack trace
     new 606bc12  SLING-2564 - adding JMX monitoring of Sling Thread Pools
     new b2e73ea  SLING-2535 wrapped the reference counter in a dedicated synchronised block to ensure that all access to the counter is safe. I think this will be safer than calling from within synchronised blocks as it doesnt rely on the caller remembering the methods need to be single threaded.
     new 9243258  SLING-2535 Undid my previous commit and put the synchronisation one layer further out as orriginally suggested. Synchronising in incUsage and decUsage is too risky from a deadlock point of view. Added Javadoc to warn about thread safety on the methods.
     new 6bb1173  Use latest releases and update to new parent pom
     new 6befbeb  Update to latest parent pom and use latest releases in launchpad
     new 5b61798  Correct reactor pom and update to parent pom 16
     new decafa3  SLING-2858 - Maven build fails after upgrading to parent 16: No annotation processors found in classpath
     new 77ccb6c  Update to latest parent pom
     new 95583d2  Update to parent pom 18
     new 5528320  [maven-release-plugin] prepare release org.apache.sling.commons.threads-3.2.0
     new 9e861b7  [maven-release-plugin] prepare for next development iteration
     new 394a1f9  Update to parent pom v19
     new a05956b  Updated to parent version 20
     new d71bd12  Update to Sling Parent POM 22 with baselining enabled
     new c7898cf  SLING-4698 - Set parent.relativePath to empty for all modules
     new 1a311ec  Update to Sling Parent 23
     new fadad3a  set parent version to 24 and add empty relativePath where missing
     new ae7b37d  Update the main reactor to parent 25
     new 4f0f0ad  SLING-5332 - Move Commons Threads to package-info.java based exports
     new 133b6f7  SLING-5333 - Commons Threads exported interfaces/classes should be @ProviderType
     new 6c5554b  SLING-4676 - Clean up threads or refresh threads when put back into the pool
     new 75dab72  [maven-release-plugin] prepare release org.apache.sling.commons.threads-3.2.2
     new 96e1f5e  [maven-release-plugin] copy for tag org.apache.sling.commons.threads-3.2.2

The 111 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-commons-threads] 07/13: set parent version to 24 and add empty relativePath where missing

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit fadad3ae0b732e2bff51d5f253f93baad7e959a3
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Tue Jul 7 08:09:17 2015 +0000

    set parent version to 24 and add empty relativePath where missing
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1689593 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 9c0015a..8b3ce05 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>23</version>
+        <version>24</version>
         <relativePath/>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 08/13: Update the main reactor to parent 25

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit ae7b37d4fbb5acd68b806da949804b0ed1bb818c
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Mon Oct 5 10:03:45 2015 +0000

    Update the main reactor to parent 25
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1706780 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 8b3ce05..32f4f9a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>24</version>
+        <version>25</version>
         <relativePath/>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 01/13: [maven-release-plugin] prepare for next development iteration

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit 9e861b73466bb791251fcb6d9c461bc1156fd2fe
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sun Oct 20 13:45:58 2013 +0000

    [maven-release-plugin] prepare for next development iteration
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1533895 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index 892f6f8..d965f28 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
 
     <artifactId>org.apache.sling.commons.threads</artifactId>
     <packaging>bundle</packaging>
-    <version>3.2.0</version>
+    <version>3.2.1-SNAPSHOT</version>
 
     <name>Apache Sling Thread Support</name>
     <description>
@@ -37,9 +37,9 @@
     </description>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.commons.threads-3.2.0</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.commons.threads-3.2.0</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.commons.threads-3.2.0</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/bundles/commons/threads</url>
     </scm>
 
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 02/13: Update to parent pom v19

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit 394a1f98999fc1ba938fada649731f135ee70ad2
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon Mar 31 14:39:20 2014 +0000

    Update to parent pom v19
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1583337 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index d965f28..8d12fc9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>18</version>
+        <version>19</version>
         <relativePath>../../../parent/pom.xml</relativePath>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 04/13: Update to Sling Parent POM 22 with baselining enabled

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit d71bd12b3f76d1fa27a9279761c04d9ba1c2ae1b
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Oct 1 06:57:44 2014 +0000

    Update to Sling Parent POM 22 with baselining enabled
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1628622 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 0fe6cd0..010da05 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>20</version>
+        <version>22</version>
         <relativePath>../../../parent/pom.xml</relativePath>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 09/13: SLING-5332 - Move Commons Threads to package-info.java based exports

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit 4f0f0ad0fce166b98752620dea2c57c668dbba6d
Author: Julian Sedding <js...@apache.org>
AuthorDate: Thu Nov 26 10:22:02 2015 +0000

    SLING-5332 - Move Commons Threads to package-info.java based exports
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1716595 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                              |  7 -------
 .../sling/commons/threads/jmx/package-info.java      | 20 ++++++++++++++++++++
 .../apache/sling/commons/threads/package-info.java   | 20 ++++++++++++++++++++
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/pom.xml b/pom.xml
index 32f4f9a..e400284 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,13 +57,6 @@
                         <Bundle-Activator>
                             org.apache.sling.commons.threads.impl.Activator
                         </Bundle-Activator>
-                        <Export-Package>
-                            org.apache.sling.commons.threads;version=3.2.0,
-                            org.apache.sling.commons.threads.jmx;version=1.0.0
-                        </Export-Package>
-                        <Private-Package>
-                            org.apache.sling.commons.threads.impl
-                        </Private-Package>
                     </instructions>
                 </configuration>
             </plugin>
diff --git a/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java b/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java
new file mode 100644
index 0000000..8a3df4d
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@Version("1.0.0")
+package org.apache.sling.commons.threads.jmx;
+
+import aQute.bnd.annotation.Version;
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/commons/threads/package-info.java b/src/main/java/org/apache/sling/commons/threads/package-info.java
new file mode 100644
index 0000000..ff46c0d
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/threads/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@Version("3.2.0")
+package org.apache.sling.commons.threads;
+
+import aQute.bnd.annotation.Version;
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 11/13: SLING-4676 - Clean up threads or refresh threads when put back into the pool

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit 6c5554b65a53a49cf77e790e8f72568a14e6d86e
Author: Julian Sedding <js...@apache.org>
AuthorDate: Thu Nov 26 10:51:38 2015 +0000

    SLING-4676 - Clean up threads or refresh threads when put back into the pool
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1716601 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  10 +
 .../threads/ModifiableThreadPoolConfig.java        |  26 +-
 .../sling/commons/threads/ThreadPoolConfig.java    |   6 +
 .../commons/threads/impl/DefaultThreadPool.java    |   7 +-
 .../threads/impl/ThreadExpiringThreadPool.java     | 146 ++++++++++
 .../commons/threads/impl/ThreadPoolMBeanImpl.java  |   4 +
 .../sling/commons/threads/jmx/ThreadPoolMBean.java |   7 +
 .../sling/commons/threads/jmx/package-info.java    |   2 +-
 .../apache/sling/commons/threads/package-info.java |   2 +-
 .../OSGI-INF/metatype/metatype.properties          |   4 +
 src/main/resources/OSGI-INF/metatype/metatype.xml  |   3 +
 .../threads/impl/ThreadExpiringThreadPoolTest.java | 316 +++++++++++++++++++++
 12 files changed, 528 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index e400284..95a65fc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -92,5 +92,15 @@
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/commons/threads/ModifiableThreadPoolConfig.java b/src/main/java/org/apache/sling/commons/threads/ModifiableThreadPoolConfig.java
index 7f62afd..bfe789d 100644
--- a/src/main/java/org/apache/sling/commons/threads/ModifiableThreadPoolConfig.java
+++ b/src/main/java/org/apache/sling/commons/threads/ModifiableThreadPoolConfig.java
@@ -19,6 +19,7 @@ package org.apache.sling.commons.threads;
 import aQute.bnd.annotation.ProviderType;
 
 import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
 
 /**
  * This is a modifiable thread pool configuration that can be instantiated
@@ -45,6 +46,8 @@ public final class ModifiableThreadPoolConfig implements ThreadPoolConfig {
     public static final String PROPERTY_MAX_POOL_SIZE = "maxPoolSize";
     /** Configuration property for the queue size. */
     public static final String PROPERTY_QUEUE_SIZE = "queueSize";
+    /** Configuration property for the max thread age. */
+    public static final String PROPERTY_MAX_THREAD_AGE = "maxThreadAge";
     /** Configuration property for the keep alive time. */
     public static final String PROPERTY_KEEP_ALIVE_TIME = "keepAliveTime";
     /** Configuration property for the block policy. */
@@ -69,6 +72,9 @@ public final class ModifiableThreadPoolConfig implements ThreadPoolConfig {
     /** The queue size */
     private int queueSize = -1;
 
+    /** Max age of a thread in milliseconds */
+    private long maxThreadAge = TimeUnit.MINUTES.toMillis(5);
+
     /** The keep alive time. */
     private long  keepAliveTime = 60000L;
 
@@ -85,7 +91,7 @@ public final class ModifiableThreadPoolConfig implements ThreadPoolConfig {
     private  ThreadFactory factory;
 
     /** Thread priority. */
-    private  ThreadPriority   priority = ThreadPriority.NORM;
+    private  ThreadPriority priority = ThreadPriority.NORM;
 
     /** Create daemon threads? */
     private  boolean isDaemon = false;
@@ -106,6 +112,7 @@ public final class ModifiableThreadPoolConfig implements ThreadPoolConfig {
             this.minPoolSize = copy.getMinPoolSize();
             this.maxPoolSize = copy.getMaxPoolSize();
             this.queueSize = copy.getQueueSize();
+            this.maxThreadAge = copy.getMaxThreadAge();
             this.keepAliveTime = copy.getKeepAliveTime();
             this.blockPolicy = copy.getBlockPolicy();
             this.shutdownGraceful = copy.isShutdownGraceful();
@@ -161,6 +168,22 @@ public final class ModifiableThreadPoolConfig implements ThreadPoolConfig {
         this.queueSize = queueSize;
     }
 
+
+    /**
+     * @see org.apache.sling.commons.threads.ThreadPoolConfig#getMaxThreadAge()
+     */
+    public long getMaxThreadAge() {
+        return maxThreadAge;
+    }
+
+    /**
+     * Set the max thread age.
+     * @param maxThreadAge New max thread age in milliseconds.
+     */
+    public void setMaxThreadAge(final long maxThreadAge) {
+        this.maxThreadAge = maxThreadAge;
+    }
+
     /**
      * @see org.apache.sling.commons.threads.ThreadPoolConfig#getKeepAliveTime()
      */
@@ -282,6 +305,7 @@ public final class ModifiableThreadPoolConfig implements ThreadPoolConfig {
             return this.minPoolSize == o.minPoolSize
                 && this.maxPoolSize == o.maxPoolSize
                 && this.queueSize == o.queueSize
+                && this.maxThreadAge == o.maxThreadAge
                 && this.keepAliveTime == o.keepAliveTime
                 && this.blockPolicy.equals(o.blockPolicy)
                 && this.shutdownGraceful == o.shutdownGraceful
diff --git a/src/main/java/org/apache/sling/commons/threads/ThreadPoolConfig.java b/src/main/java/org/apache/sling/commons/threads/ThreadPoolConfig.java
index 74cbf76..6bb641f 100644
--- a/src/main/java/org/apache/sling/commons/threads/ThreadPoolConfig.java
+++ b/src/main/java/org/apache/sling/commons/threads/ThreadPoolConfig.java
@@ -59,6 +59,12 @@ public interface ThreadPoolConfig {
     int getQueueSize();
 
     /**
+     * Return the maximum age before a thread is retired.
+     * @return The maximum age of a thread in milliseconds.
+     */
+    long getMaxThreadAge();
+
+    /**
      * Return the keep alive time.
      * @return The keep alive time.
      */
diff --git a/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPool.java b/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPool.java
index 81b8740..4f5a1a2 100644
--- a/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPool.java
+++ b/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPool.java
@@ -126,8 +126,11 @@ public class DefaultThreadPool
                 handler = new ThreadPoolExecutor.CallerRunsPolicy();
                 break;
         }
-        this.executor = new ThreadPoolExecutor(this.configuration.getMinPoolSize(),
+
+        this.executor = new ThreadExpiringThreadPool(this.configuration.getMinPoolSize(),
                 this.configuration.getMaxPoolSize(),
+                this.configuration.getMaxThreadAge(),
+                TimeUnit.MILLISECONDS,
                 this.configuration.getKeepAliveTime(),
                 TimeUnit.MILLISECONDS,
                 queue,
@@ -204,7 +207,7 @@ public class DefaultThreadPool
                         logger.warn("Running commands have not terminated within "
                             + this.configuration.getShutdownWaitTimeMs()
                             + "ms. Will shut them down by interruption");
-                        this.executor.shutdownNow();
+                        this.executor.shutdownNow(); // TODO: shouldn't this be outside the if statement?!
                     }
                 }
             } catch (final InterruptedException ie) {
diff --git a/src/main/java/org/apache/sling/commons/threads/impl/ThreadExpiringThreadPool.java b/src/main/java/org/apache/sling/commons/threads/impl/ThreadExpiringThreadPool.java
new file mode 100644
index 0000000..ec5bab4
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/threads/impl/ThreadExpiringThreadPool.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.commons.threads.impl;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * An extension of ThreadPoolExecutor, which keeps track of the age
+ * of the worker threads and expires them when they get older than
+ * a specified max-age.
+ * <br/>
+ * To be precise, a thread is expired when it finishes processing
+ * a task and its max-age has been exceeded at that time. I.e. if a
+ * thread is idle past its expiry, it may still process a single
+ * task before it is expired.
+ */
+public class ThreadExpiringThreadPool extends ThreadPoolExecutor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThreadExpiringThreadPool.class);
+
+    /**
+     * Map from thread-id to the time (in milliseconds) when a thread was first used to
+     * process a task. This is used to look determine when a thread is to be expired.
+     */
+    private final ConcurrentHashMap<Long, Long> threadStartTimes;
+
+    /**
+     * Thread max-age in milliseconds.
+     */
+    private final long maxThreadAge;
+
+    /**
+     * Convenience flag indicating whether threads expire or not.
+     * This is equivalent to {@code maxThreadAge >= 0}.
+     */
+    private final boolean enableThreadExpiry;
+
+    /**
+     * Marker exception object thrown to terminate threads that have
+     * reached or exceeded their max-age. This exception is intentionally
+     * used for (minimal) control flow, i.e. the {@code ThreadPoolExecutor}
+     * will dispose of any thread that threw an exception and create a new
+     * one in its stead. This exception should never show up in any logs,
+     * otherwise it is a bug.
+     */
+    private final RuntimeException expiredThreadException;
+
+    public ThreadExpiringThreadPool(
+            final int corePoolSize,
+            final int maximumPoolSize,
+            final long maxThreadAge,
+            final TimeUnit maxThreadAgeUnit,
+            final long keepAliveTime,
+            final TimeUnit keepAliveTimeUnit,
+            final BlockingQueue<Runnable> workQueue,
+            final ThreadFactory threadFactory,
+            final RejectedExecutionHandler handler
+    ) {
+        super(corePoolSize, maximumPoolSize, keepAliveTime, keepAliveTimeUnit, workQueue, threadFactory, handler);
+        this.threadStartTimes = new ConcurrentHashMap<Long, Long>(maximumPoolSize);
+        this.maxThreadAge = TimeUnit.MILLISECONDS.convert(maxThreadAge, maxThreadAgeUnit);
+        this.enableThreadExpiry = maxThreadAge >= 0;
+        this.expiredThreadException = new RuntimeException("Kill old thread");
+    }
+
+    @Override
+    protected void beforeExecute(final Thread thread, final Runnable runnable) {
+        if (enableThreadExpiry) {
+            recordStartTime(thread);
+        }
+        super.beforeExecute(thread, runnable);
+    }
+
+    private void recordStartTime(final Thread thread) {
+        final long threadId = thread.getId();
+        if (threadStartTimes.putIfAbsent(threadId, System.currentTimeMillis()) == null) {
+            LOG.debug("{} used for the first time.", thread);
+
+            // The uncaught exception handler makes sure that the exception
+            // signalling the death of a thread is swallowed. All other
+            // Throwables are handed to the originalHandler.
+            final Thread.UncaughtExceptionHandler originalHandler = thread.getUncaughtExceptionHandler();
+            thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+                @Override
+                public void uncaughtException(final Thread thread, final Throwable throwable) {
+                    // first reset the original uncaught exception handler - just as a precaution
+                    thread.setUncaughtExceptionHandler(originalHandler);
+
+                    // ignore expected exception thrown to terminate the thread
+                    if (throwable == expiredThreadException) {
+                        return;
+                    }
+
+                    // delegate any other exceptions to the original uncaught exception handler
+                    if (originalHandler != null) {
+                        originalHandler.uncaughtException(thread, throwable);
+                    }
+                }
+            });
+        }
+    }
+
+    @Override
+    protected void afterExecute(final Runnable runnable, final Throwable throwable) {
+        super.afterExecute(runnable, throwable);
+        if (throwable == null && enableThreadExpiry) {
+            checkMaxThreadAge(Thread.currentThread());
+        }
+    }
+
+    private void checkMaxThreadAge(final Thread thread) {
+        final long now = System.currentTimeMillis();
+        final long threadId = thread.getId();
+        final Long started = threadStartTimes.get(threadId);
+        if (started != null && now >= started + maxThreadAge) {
+            final long delta = now - (started + maxThreadAge);
+            LOG.debug("{} exceeded its max age by {}ms and will be replaced.", thread, delta);
+            threadStartTimes.remove(threadId);
+
+            // throw marker exception to kill this thread and thus trigger creation of a new one
+            throw expiredThreadException;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/commons/threads/impl/ThreadPoolMBeanImpl.java b/src/main/java/org/apache/sling/commons/threads/impl/ThreadPoolMBeanImpl.java
index fe96b97..bed13a1 100644
--- a/src/main/java/org/apache/sling/commons/threads/impl/ThreadPoolMBeanImpl.java
+++ b/src/main/java/org/apache/sling/commons/threads/impl/ThreadPoolMBeanImpl.java
@@ -100,6 +100,10 @@ class ThreadPoolMBeanImpl extends StandardMBean implements ThreadPoolMBean {
         }
     }
 
+    public long getMaxThreadAge() {
+        return this.entry.getConfig().getMaxThreadAge();
+    }
+
     public long getKeepAliveTime() {
         return this.entry.getConfig().getKeepAliveTime();
     }
diff --git a/src/main/java/org/apache/sling/commons/threads/jmx/ThreadPoolMBean.java b/src/main/java/org/apache/sling/commons/threads/jmx/ThreadPoolMBean.java
index 1674111..e933b91 100644
--- a/src/main/java/org/apache/sling/commons/threads/jmx/ThreadPoolMBean.java
+++ b/src/main/java/org/apache/sling/commons/threads/jmx/ThreadPoolMBean.java
@@ -83,6 +83,13 @@ public interface ThreadPoolMBean {
     long getExecutorTaskCount();
 
     /**
+     * Return the configured max thread age.
+     *
+     * @return The configured max thread age.
+     */
+    long getMaxThreadAge();
+
+    /**
      * Return the configured keep alive time.
      * 
      * @return The configured keep alive time.
diff --git a/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java b/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java
index 2e9107f..53dcb2e 100644
--- a/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java
+++ b/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.0.1")
+@Version("1.1.0")
 package org.apache.sling.commons.threads.jmx;
 
 import aQute.bnd.annotation.Version;
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/commons/threads/package-info.java b/src/main/java/org/apache/sling/commons/threads/package-info.java
index b7b9b97..3e2b736 100644
--- a/src/main/java/org/apache/sling/commons/threads/package-info.java
+++ b/src/main/java/org/apache/sling/commons/threads/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("3.2.1")
+@Version("3.3.0")
 package org.apache.sling.commons.threads;
 
 import aQute.bnd.annotation.Version;
\ No newline at end of file
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties
index 4108496..eccce0e 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -32,6 +32,10 @@ maxPoolSize.description=The maximum pool size.
 queueSize.name=Queue Size
 queueSize.description=The queue size or -1 for an unlimited queue size.
 
+maxThreadAge.name=Max Thread Age
+maxThreadAge.description=Milliseconds before a pooled thread is replaced (-1 to disable expiry). \
+  Useful to avoid memory leaks by accumulation of ThreadLocals.
+
 keepAliveTime.name=Keep Alive Time
 keepAliveTime.description=The keep alive time.
 
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.xml b/src/main/resources/OSGI-INF/metatype/metatype.xml
index a6c3f73..f1f7f4d 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.xml
+++ b/src/main/resources/OSGI-INF/metatype/metatype.xml
@@ -37,6 +37,9 @@
         <metatype:AD id="queueSize"
             type="Integer" default="-1" name="%queueSize.name"
             description="%queueSize.description" />
+        <metatype:AD id="maxThreadAge"
+            type="Long" default="300000" name="%maxThreadAge.name"
+            description="%maxThreadAge.description" />
         <metatype:AD id="keepAliveTime"
             type="Long" default="60000" name="%keepAliveTime.name"
             description="%keepAliveTime.description" />
diff --git a/src/test/java/org/apache/sling/commons/threads/impl/ThreadExpiringThreadPoolTest.java b/src/test/java/org/apache/sling/commons/threads/impl/ThreadExpiringThreadPoolTest.java
new file mode 100644
index 0000000..80c0e4f
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/threads/impl/ThreadExpiringThreadPoolTest.java
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.commons.threads.impl;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExternalResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class ThreadExpiringThreadPoolTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThreadExpiringThreadPoolTest.class);
+
+    private static final int MAX_THREAD_AGE_MS = 15; // let threads expire after this many ms
+
+    @Rule
+    public ThreadPoolContext context = new ThreadPoolContext();
+
+    @Test
+    public void shouldCreateNewThreadAfterExpiry() throws InterruptedException, ExecutionException {
+        final TrackingThreadFactory threadFactory = context.getThreadFactory();
+        final ThreadExpiringThreadPool pool = context.getPool();
+
+        assertThat(threadFactory.getThreadCount(), is(0));
+
+        assertExecutionByThread(pool, "test-thread-0");
+        assertExecutionByThread(pool, "test-thread-0");
+        assertExecutionByThread(pool, "test-thread-0");
+        assertThat(threadFactory.getThreadCount(), is(1));
+
+        letThreadsDie();
+
+        // thread executes one more task after expiring
+        assertExecutionByThread(pool, "test-thread-0");
+        assertExecutionByThread(pool, "test-thread-1");
+        assertThat(threadFactory.getThreadCount(), is(2));
+
+        assertActiveThreads(threadFactory, "test-thread-1");
+        assertExpiredThreads(threadFactory, "test-thread-0");
+    }
+
+    @Test
+    public void shouldCreateNewThreadAfterExpiryForFailingTasks() throws InterruptedException, ExecutionException {
+        final TrackingThreadFactory threadFactory = context.getThreadFactory();
+        final ThreadExpiringThreadPool pool = context.getPool();
+
+        assertThat(threadFactory.getThreadCount(), is(0));
+
+        assertFailingSubmitThreadName(pool, "test-thread-0");
+        assertFailingSubmitThreadName(pool, "test-thread-0");
+        assertFailingSubmitThreadName(pool, "test-thread-0");
+        assertThat(threadFactory.getThreadCount(), is(1));
+
+        letThreadsDie();
+
+        // thread executes one more task after expiring
+        assertFailingSubmitThreadName(pool, "test-thread-0");
+        assertFailingSubmitThreadName(pool, "test-thread-1");
+        assertThat(threadFactory.getThreadCount(), is(2));
+
+        assertActiveThreads(threadFactory, "test-thread-1");
+        assertExpiredThreads(threadFactory, "test-thread-0");
+    }
+
+    @Test
+    public void shouldLetMultipleThreadsDieAfterExpiry()
+            throws ExecutionException, InterruptedException {
+
+        final TrackingThreadFactory threadFactory = context.getThreadFactory();
+        final ThreadExpiringThreadPool pool = context.getPool();
+        pool.setCorePoolSize(3);
+        pool.setMaximumPoolSize(3);
+
+        assertParallelExecutionsByThread(pool, "test-thread-0", "test-thread-1", "test-thread-2");
+        assertThat(threadFactory.getThreadCount(), is(3));
+
+        letThreadsDie();
+        // thread executes one more task after expiring
+        executeParallelTasks(pool, 3);
+
+        assertParallelExecutionsByThread(pool, "test-thread-3", "test-thread-4", "test-thread-5");
+        assertThat(threadFactory.getThreadCount(), is(6));
+
+        assertActiveThreads(threadFactory, "test-thread-3", "test-thread-4", "test-thread-5");
+        assertExpiredThreads(threadFactory, "test-thread-0", "test-thread-1", "test-thread-2");
+    }
+
+    private void assertActiveThreads(final TrackingThreadFactory factory, final String... names) {
+        assertThat("Active threads", factory.getActiveThreads(), equalTo(asSet(names)));
+    }
+
+    private void assertExpiredThreads(final TrackingThreadFactory factory, final String... names) {
+        assertThat("Expired threads", factory.getExpiredThreads(), equalTo(asSet(names)));
+    }
+
+    private Set<String> asSet(final String... items) {
+        return new HashSet<String>(asList(items));
+    }
+
+    private void assertParallelExecutionsByThread(final ExecutorService pool, final String... expectedThreads)
+            throws InterruptedException {
+
+        final Task[] tasks = executeParallelTasks(pool, 3);
+        final List<String> threadNames = new ArrayList<String>();
+        for (final Task task : tasks) {
+            threadNames.add(task.executedBy);
+        }
+        for (final String expectedThread : expectedThreads) {
+            assertTrue("No task was executed by " + expectedThread,
+                    threadNames.remove(expectedThread));
+            assertFalse("Multiple tasks were executed by " + expectedThread,
+                    threadNames.contains(expectedThread));
+        }
+    }
+
+    private Task[] executeParallelTasks(final ExecutorService pool, final int number)
+            throws InterruptedException {
+        final Task[] tasks = new Task[number];
+        final CountDownLatch latch = new CountDownLatch(number);
+        for (int i = 0; i < tasks.length; i++) {
+            tasks[i] = new Task(latch);
+            pool.execute(tasks[i]);
+        }
+        pool.awaitTermination(MAX_THREAD_AGE_MS, TimeUnit.MILLISECONDS);
+        return tasks;
+    }
+
+    private void assertExecutionByThread(final ExecutorService pool, final String expectedThread)
+            throws ExecutionException, InterruptedException {
+        final Task task = new Task();
+        pool.submit(task).get();
+        assertEquals("Thread name", expectedThread, task.executedBy);
+    }
+
+    private void assertFailingSubmitThreadName(final ExecutorService pool, final String expectedThread)
+            throws ExecutionException, InterruptedException {
+        final Task task = new ExceptionTask();
+        try {
+            pool.submit(task).get();
+        } catch (ExecutionException e) {
+            if (!e.getCause().getMessage().startsWith("ExceptionTask #")) {
+                LOG.error("Unexpected exception: ", e);
+                fail("Unexpected exception: " + e.getMessage());
+            }
+        }
+        assertEquals("Thread name", expectedThread, task.executedBy);
+    }
+
+    private void letThreadsDie() throws InterruptedException {
+        TimeUnit.MILLISECONDS.sleep(MAX_THREAD_AGE_MS * 2);
+    }
+
+    private static class Task implements Runnable {
+
+        private static int counter = 0;
+
+        protected final int count;
+
+        private final CountDownLatch mayFinish;
+
+        protected String executedBy;
+
+        Task() {
+            this(new CountDownLatch(0));
+        }
+
+        Task(final CountDownLatch latch) {
+            this.mayFinish = latch;
+            this.count = counter++;
+        }
+
+        @Override
+        public void run() {
+            mayFinish.countDown();
+            final Thread thread = Thread.currentThread();
+            try {
+                mayFinish.await();
+            } catch (InterruptedException e) {
+                thread.interrupt();
+            }
+            LOG.info("{} #{} running in thread {}",
+                    new Object[] {getClass().getSimpleName(), count, thread});
+            executedBy = thread.getName();
+        }
+    }
+
+    private static class ExceptionTask extends Task {
+        @Override
+        public void run() {
+            super.run();
+            throw new RuntimeException("ExceptionTask #" + count);
+        }
+    }
+
+    private static class TrackingThreadFactory implements ThreadFactory {
+
+        private final ThreadGroup group;
+
+        private final AtomicInteger threadCount = new AtomicInteger(0);
+
+        private final List<Thread> threadHistory = new CopyOnWriteArrayList<Thread>();
+
+        public TrackingThreadFactory() {
+            group = Thread.currentThread().getThreadGroup();
+        }
+
+        public int getThreadCount() {
+            return threadHistory.size();
+        }
+
+        public Set<String> getActiveThreads() {
+            final HashSet<String> active = new HashSet<String>();
+            for (final Thread thread : threadHistory) {
+                if (thread.isAlive()) {
+                    active.add(thread.getName());
+                }
+            }
+            return active;
+        }
+
+        public Set<String> getExpiredThreads() {
+            final HashSet<String> expired = new HashSet<String>();
+            for (final Thread thread : threadHistory) {
+                if (!thread.isAlive()) {
+                    expired.add(thread.getName());
+                }
+            }
+            return expired;
+        }
+
+        @Override
+        public Thread newThread(final Runnable r) {
+            final Thread thread = new Thread(group, r, "test-thread-" + threadCount.getAndIncrement());
+            thread.setDaemon(false);
+            thread.setPriority(Thread.NORM_PRIORITY);
+            threadHistory.add(thread);
+            LOG.info("Created thread {}", thread.getName());
+            return thread;
+        }
+    }
+
+    public static class ThreadPoolContext extends ExternalResource {
+
+        public TrackingThreadFactory getThreadFactory() {
+            return threadFactory;
+        }
+
+        public ThreadExpiringThreadPool getPool() {
+            return pool;
+        }
+
+        private TrackingThreadFactory threadFactory;
+
+        private ThreadExpiringThreadPool pool;
+
+        @Override
+        protected void before() throws Throwable {
+            Task.counter = 0; // reset counter
+            final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(20);
+            final RejectedExecutionHandler rejectionHandler = new ThreadPoolExecutor.AbortPolicy();
+            threadFactory = new TrackingThreadFactory();
+            pool = new ThreadExpiringThreadPool(
+                    1, 1,
+                    MAX_THREAD_AGE_MS, TimeUnit.MILLISECONDS,
+                    1000, TimeUnit.MILLISECONDS,
+                    queue, threadFactory, rejectionHandler);
+        }
+
+        @Override
+        protected void after() {
+            threadFactory = null;
+            pool = null;
+        }
+    }
+}
+

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 12/13: [maven-release-plugin] prepare release org.apache.sling.commons.threads-3.2.2

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit 75dab7262f7a757b1a1fb76e69fd0b55389061be
Author: Julian Sedding <js...@apache.org>
AuthorDate: Thu Nov 26 16:44:55 2015 +0000

    [maven-release-plugin] prepare release org.apache.sling.commons.threads-3.2.2
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1716739 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index 95a65fc..ee7baf0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,12 +24,12 @@
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
         <version>25</version>
-        <relativePath/>
+        <relativePath />
     </parent>
 
     <artifactId>org.apache.sling.commons.threads</artifactId>
     <packaging>bundle</packaging>
-    <version>3.2.1-SNAPSHOT</version>
+    <version>3.2.2</version>
 
     <name>Apache Sling Thread Support</name>
     <description>
@@ -37,9 +37,9 @@
     </description>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/bundles/commons/threads</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.commons.threads-3.2.2</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.commons.threads-3.2.2</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.commons.threads-3.2.2</url>
     </scm>
 
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 05/13: SLING-4698 - Set parent.relativePath to empty for all modules

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit c7898cffb99049bdd646d1fbce88b0d1fc3d8b2e
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 7 10:14:40 2015 +0000

    SLING-4698 - Set parent.relativePath to empty for all modules
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1678154 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 010da05..b695e43 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
         <version>22</version>
-        <relativePath>../../../parent/pom.xml</relativePath>
+        <relativePath/>
     </parent>
 
     <artifactId>org.apache.sling.commons.threads</artifactId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 13/13: [maven-release-plugin] copy for tag org.apache.sling.commons.threads-3.2.2

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit 96e1f5e8c85f37cb8bf82820a900fbb276949020
Author: Julian Sedding <js...@apache.org>
AuthorDate: Thu Nov 26 16:45:09 2015 +0000

    [maven-release-plugin] copy for tag org.apache.sling.commons.threads-3.2.2
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.commons.threads-3.2.2@1716740 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 03/13: Updated to parent version 20

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit a05956b1f68860879cc839bd96ad846a82aa8dc9
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Aug 1 19:16:26 2014 +0000

    Updated to parent version 20
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1615208 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 8d12fc9..0fe6cd0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>19</version>
+        <version>20</version>
         <relativePath>../../../parent/pom.xml</relativePath>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 06/13: Update to Sling Parent 23

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit 1a311ec948b27c2ef990b4ede5f27bb4b167a0e8
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu Jun 25 13:08:16 2015 +0000

    Update to Sling Parent 23
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1687500 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index b695e43..9c0015a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>22</version>
+        <version>23</version>
         <relativePath/>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-threads] 10/13: SLING-5333 - Commons Threads exported interfaces/classes should be @ProviderType

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.2.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git

commit 133b6f72045c1485898b056edcbe4bdb35176998
Author: Julian Sedding <js...@apache.org>
AuthorDate: Thu Nov 26 10:33:27 2015 +0000

    SLING-5333 - Commons Threads exported interfaces/classes should be @ProviderType
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@1716599 13f79535-47bb-0310-9956-ffa450edef68
---
 .../org/apache/sling/commons/threads/ModifiableThreadPoolConfig.java   | 3 +++
 src/main/java/org/apache/sling/commons/threads/ThreadPool.java         | 3 +++
 src/main/java/org/apache/sling/commons/threads/ThreadPoolConfig.java   | 3 +++
 src/main/java/org/apache/sling/commons/threads/ThreadPoolManager.java  | 3 +++
 .../java/org/apache/sling/commons/threads/jmx/ThreadPoolMBean.java     | 3 +++
 src/main/java/org/apache/sling/commons/threads/jmx/package-info.java   | 2 +-
 src/main/java/org/apache/sling/commons/threads/package-info.java       | 2 +-
 7 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/apache/sling/commons/threads/ModifiableThreadPoolConfig.java b/src/main/java/org/apache/sling/commons/threads/ModifiableThreadPoolConfig.java
index 51bd166..7f62afd 100644
--- a/src/main/java/org/apache/sling/commons/threads/ModifiableThreadPoolConfig.java
+++ b/src/main/java/org/apache/sling/commons/threads/ModifiableThreadPoolConfig.java
@@ -16,6 +16,8 @@
  */
 package org.apache.sling.commons.threads;
 
+import aQute.bnd.annotation.ProviderType;
+
 import java.util.concurrent.ThreadFactory;
 
 /**
@@ -34,6 +36,7 @@ import java.util.concurrent.ThreadFactory;
  * - daemon: false
  * - factory: null (= default jvm thread factory)
  */
+@ProviderType
 public final class ModifiableThreadPoolConfig implements ThreadPoolConfig {
 
     /** Configuration property for the min pool size. */
diff --git a/src/main/java/org/apache/sling/commons/threads/ThreadPool.java b/src/main/java/org/apache/sling/commons/threads/ThreadPool.java
index 746206c..7fa8c16 100644
--- a/src/main/java/org/apache/sling/commons/threads/ThreadPool.java
+++ b/src/main/java/org/apache/sling/commons/threads/ThreadPool.java
@@ -16,6 +16,8 @@
  */
 package org.apache.sling.commons.threads;
 
+import aQute.bnd.annotation.ProviderType;
+
 import java.util.concurrent.Callable;
 import java.util.concurrent.Future;
 
@@ -23,6 +25,7 @@ import java.util.concurrent.Future;
  * The thread pool interface allows to start runnables by
  * getting threads from a managed pool.
  */
+@ProviderType
 public interface ThreadPool {
 
     /**
diff --git a/src/main/java/org/apache/sling/commons/threads/ThreadPoolConfig.java b/src/main/java/org/apache/sling/commons/threads/ThreadPoolConfig.java
index 57fe344..74cbf76 100644
--- a/src/main/java/org/apache/sling/commons/threads/ThreadPoolConfig.java
+++ b/src/main/java/org/apache/sling/commons/threads/ThreadPoolConfig.java
@@ -16,11 +16,14 @@
  */
 package org.apache.sling.commons.threads;
 
+import aQute.bnd.annotation.ProviderType;
+
 import java.util.concurrent.ThreadFactory;
 
 /**
  * The thread pool configuration.
  */
+@ProviderType
 public interface ThreadPoolConfig {
 
     /** The thread pool policies. */
diff --git a/src/main/java/org/apache/sling/commons/threads/ThreadPoolManager.java b/src/main/java/org/apache/sling/commons/threads/ThreadPoolManager.java
index fa69df2..3fecfbb 100644
--- a/src/main/java/org/apache/sling/commons/threads/ThreadPoolManager.java
+++ b/src/main/java/org/apache/sling/commons/threads/ThreadPoolManager.java
@@ -17,10 +17,13 @@
 package org.apache.sling.commons.threads;
 
 
+import aQute.bnd.annotation.ProviderType;
+
 /**
  * The <code>ThreadPoolManager</code> manages thread pools.
  *
  */
+@ProviderType
 public interface ThreadPoolManager {
 
     /** The default thread pool name */
diff --git a/src/main/java/org/apache/sling/commons/threads/jmx/ThreadPoolMBean.java b/src/main/java/org/apache/sling/commons/threads/jmx/ThreadPoolMBean.java
index bdee6b3..1674111 100644
--- a/src/main/java/org/apache/sling/commons/threads/jmx/ThreadPoolMBean.java
+++ b/src/main/java/org/apache/sling/commons/threads/jmx/ThreadPoolMBean.java
@@ -16,9 +16,12 @@
  */
 package org.apache.sling.commons.threads.jmx;
 
+import aQute.bnd.annotation.ProviderType;
+
 /**
  * This is the management interface for a Sling Thread Pool.
  */
+@ProviderType
 public interface ThreadPoolMBean {
 
     /**
diff --git a/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java b/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java
index 8a3df4d..2e9107f 100644
--- a/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java
+++ b/src/main/java/org/apache/sling/commons/threads/jmx/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.0.0")
+@Version("1.0.1")
 package org.apache.sling.commons.threads.jmx;
 
 import aQute.bnd.annotation.Version;
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/commons/threads/package-info.java b/src/main/java/org/apache/sling/commons/threads/package-info.java
index ff46c0d..b7b9b97 100644
--- a/src/main/java/org/apache/sling/commons/threads/package-info.java
+++ b/src/main/java/org/apache/sling/commons/threads/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("3.2.0")
+@Version("3.2.1")
 package org.apache.sling.commons.threads;
 
 import aQute.bnd.annotation.Version;
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.