You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2011/01/04 15:53:06 UTC
svn commit: r1055068 - in
/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene:
AbstractIndex.java DynamicPooledExecutor.java
Author: jukka
Date: Tue Jan 4 14:53:06 2011
New Revision: 1055068
URL: http://svn.apache.org/viewvc?rev=1055068&view=rev
Log:
JCR-2836: Unclosed threads in Jackrabbit
Automatically close the DynamicPooledExecutor threads when no longer used.
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DynamicPooledExecutor.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java?rev=1055068&r1=1055067&r2=1055068&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java Tue Jan 4 14:53:06 2011
@@ -63,7 +63,7 @@ abstract class AbstractIndex {
private static final LoggingPrintStream STREAM_LOGGER = new LoggingPrintStream();
/** Executor with a pool size equal to the number of available processors */
- private static final DynamicPooledExecutor EXECUTOR = new DynamicPooledExecutor();
+ private final DynamicPooledExecutor executor = new DynamicPooledExecutor();
/** The currently set IndexWriter or <code>null</code> if none is set */
private IndexWriter indexWriter;
@@ -181,7 +181,7 @@ abstract class AbstractIndex {
final IndexWriter writer = getIndexWriter();
for (final Document doc : docs) {
- EXECUTOR.execute(new Runnable() {
+ executor.execute(new Runnable() {
public void run() {
try {
// check if text extractor completed its work
@@ -409,6 +409,7 @@ abstract class AbstractIndex {
directory = null;
}
}
+ executor.close();
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DynamicPooledExecutor.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DynamicPooledExecutor.java?rev=1055068&r1=1055067&r2=1055068&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DynamicPooledExecutor.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DynamicPooledExecutor.java Tue Jan 4 14:53:06 2011
@@ -30,37 +30,32 @@ import java.util.concurrent.TimeUnit;
public class DynamicPooledExecutor implements Executor {
/**
+ * Number of instances that access the underlying executor.
+ * Used to automatically shutdown the thread pool when unused.
+ */
+ private static int instances = 0;
+
+ /**
* The underlying pooled executor.
*/
- private final ThreadPoolExecutor executor;
+ private static ThreadPoolExecutor executor = null;
/**
* The time (in milliseconds) when the pool size was last checked.
*/
- private long lastCheck;
+ private static long lastCheck;
/**
* Creates a new DynamicPooledExecutor.
*/
public DynamicPooledExecutor() {
- ThreadFactory f = new ThreadFactory() {
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r, "DynamicPooledExecutor");
- t.setDaemon(true);
- return t;
- }
- };
- this.executor = new ThreadPoolExecutor(
- 1, Runtime.getRuntime().availableProcessors(),
- 500, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue<Runnable>(), f);
- this.lastCheck = System.currentTimeMillis();
+ startInstance();
}
/**
* Adjusts the pool size at most once every second.
*/
- private synchronized void adjustPoolSize() {
+ private static synchronized ThreadPoolExecutor adjustPoolSize() {
long now = System.currentTimeMillis();
if (lastCheck + 1000 < now) {
int n = Runtime.getRuntime().availableProcessors();
@@ -69,6 +64,7 @@ public class DynamicPooledExecutor imple
}
lastCheck = now;
}
+ return executor;
}
/**
@@ -81,7 +77,7 @@ public class DynamicPooledExecutor imple
* @param command the command to execute.
*/
public void execute(Runnable command) {
- adjustPoolSize();
+ ThreadPoolExecutor executor = adjustPoolSize();
if (executor.getMaximumPoolSize() == 1) {
// if there is only one processor execute with current thread
command.run();
@@ -90,4 +86,39 @@ public class DynamicPooledExecutor imple
}
}
+ public void close() {
+ stopInstance();
+ }
+
+ private static synchronized void startInstance() {
+ instances++;
+ if (executor == null) {
+ ThreadFactory f = new ThreadFactory() {
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r, "DynamicPooledExecutor");
+ t.setDaemon(true);
+ return t;
+ }
+ };
+ executor = new ThreadPoolExecutor(
+ 1, Runtime.getRuntime().availableProcessors(),
+ 500, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>(), f);
+ lastCheck = System.currentTimeMillis();
+ }
+ }
+
+ private static synchronized void stopInstance() {
+ instances--;
+ if (instances == 0) {
+ executor.shutdown();
+ try {
+ executor.awaitTermination(10, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ // ignore and continue
+ }
+ executor = null;
+ }
+ }
+
}