This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opennlp.git
The following commit(s) were added to refs/heads/main by this push:
new ccca8ca5 OPENNLP-1620 - It should be possible to remove the allocated
ThreadLocal
ccca8ca5 is described below
commit ccca8ca5d5f95ae9af9b23126e6611058605bb17
Author: Richard Zowalla <[email protected]>
AuthorDate: Tue Oct 15 13:25:30 2024 +0200
OPENNLP-1620 - It should be possible to remove the allocated ThreadLocal
---
.../tools/postag/ThreadSafePOSTaggerME.java | 16 ++++++++++++++-
.../sentdetect/ThreadSafeSentenceDetectorME.java | 24 +++++++++++++++-------
.../tools/tokenize/ThreadSafeTokenizerME.java | 22 ++++++++++++++++----
3 files changed, 50 insertions(+), 12 deletions(-)
diff --git
a/opennlp-tools/src/main/java/opennlp/tools/postag/ThreadSafePOSTaggerME.java
b/opennlp-tools/src/main/java/opennlp/tools/postag/ThreadSafePOSTaggerME.java
index 52419ddf..b567f1ea 100644
---
a/opennlp-tools/src/main/java/opennlp/tools/postag/ThreadSafePOSTaggerME.java
+++
b/opennlp-tools/src/main/java/opennlp/tools/postag/ThreadSafePOSTaggerME.java
@@ -23,9 +23,18 @@ import opennlp.tools.util.Sequence;
/**
* A thread-safe version of the POSTaggerME. Using it is completely
transparent. You can use it in
* a single-threaded context as well, it only incurs a minimal overhead.
+ * <p>
+ * Note, however, that this implementation uses a {@link ThreadLocal}.
Although the implementation is
+ * lightweight because the model is not duplicated, if you have many
long-running threads,
+ * you may run into memory problems.
+ * </p>
+ * <p>
+ * Be careful when using this in a Jakarta EE application, for example.
+ * </p>
+ * The user is responsible for clearing the {@link ThreadLocal}.
*/
@ThreadSafe
-public class ThreadSafePOSTaggerME implements POSTagger {
+public class ThreadSafePOSTaggerME implements POSTagger, AutoCloseable {
private final POSModel model;
@@ -64,4 +73,9 @@ public class ThreadSafePOSTaggerME implements POSTagger {
public Sequence[] topKSequences(String[] sentence, Object[]
additionaContext) {
return getTagger().topKSequences(sentence, additionaContext);
}
+
+ @Override
+ public void close() {
+ threadLocal.remove();
+ }
}
diff --git
a/opennlp-tools/src/main/java/opennlp/tools/sentdetect/ThreadSafeSentenceDetectorME.java
b/opennlp-tools/src/main/java/opennlp/tools/sentdetect/ThreadSafeSentenceDetectorME.java
index 99abc6fb..17ea14e8 100644
---
a/opennlp-tools/src/main/java/opennlp/tools/sentdetect/ThreadSafeSentenceDetectorME.java
+++
b/opennlp-tools/src/main/java/opennlp/tools/sentdetect/ThreadSafeSentenceDetectorME.java
@@ -24,16 +24,21 @@ import opennlp.tools.util.Span;
* A thread-safe version of SentenceDetectorME. Using it is completely
transparent. You can use it in
* a single-threaded context as well, it only incurs a minimal overhead.
* <p>
- * Note, however, that this implementation uses a ThreadLocal. Although the
implementation is
- * lightweight as the model is not duplicated, if you have many long-running
threads, you may run
- * into memory issues. Be careful when you use this in a JEE application, for
example.
+ * Note, however, that this implementation uses a {@link ThreadLocal}.
Although the implementation is
+ * lightweight because the model is not duplicated, if you have many
long-running threads,
+ * you may run into memory problems.
+ * </p>
+ * <p>
+ * Be careful when using this in a Jakarta EE application, for example.
+ * </p>
+ * The user is responsible for clearing the {@link ThreadLocal}.
*/
@ThreadSafe
-public class ThreadSafeSentenceDetectorME implements SentenceDetector {
+public class ThreadSafeSentenceDetectorME implements SentenceDetector,
AutoCloseable {
private final SentenceModel model;
- private final ThreadLocal<SentenceDetectorME> sentenceDetectorThreadLocal =
+ private final ThreadLocal<SentenceDetectorME> threadLocal =
new ThreadLocal<>();
public ThreadSafeSentenceDetectorME(SentenceModel model) {
@@ -43,10 +48,10 @@ public class ThreadSafeSentenceDetectorME implements
SentenceDetector {
// If a thread-local version exists, return it. Otherwise, create, then
return.
private SentenceDetectorME getSD() {
- SentenceDetectorME sd = sentenceDetectorThreadLocal.get();
+ SentenceDetectorME sd = threadLocal.get();
if (sd == null) {
sd = new SentenceDetectorME(model);
- sentenceDetectorThreadLocal.set(sd);
+ threadLocal.set(sd);
}
return sd;
}
@@ -64,4 +69,9 @@ public class ThreadSafeSentenceDetectorME implements
SentenceDetector {
public Span[] sentPosDetect(CharSequence s) {
return getSD().sentPosDetect(s);
}
+
+ @Override
+ public void close() {
+ threadLocal.remove();
+ }
}
diff --git
a/opennlp-tools/src/main/java/opennlp/tools/tokenize/ThreadSafeTokenizerME.java
b/opennlp-tools/src/main/java/opennlp/tools/tokenize/ThreadSafeTokenizerME.java
index b92dd5e0..3ebbd1e3 100644
---
a/opennlp-tools/src/main/java/opennlp/tools/tokenize/ThreadSafeTokenizerME.java
+++
b/opennlp-tools/src/main/java/opennlp/tools/tokenize/ThreadSafeTokenizerME.java
@@ -23,13 +23,22 @@ import opennlp.tools.util.Span;
/**
* A thread-safe version of TokenizerME. Using it is completely transparent.
You can use it in
* a single-threaded context as well, it only incurs a minimal overhead.
+ * <p>
+ * Note, however, that this implementation uses a {@link ThreadLocal}.
Although the implementation is
+ * lightweight because the model is not duplicated, if you have many
long-running threads,
+ * you may run into memory problems.
+ * </p>
+ * <p>
+ * Be careful when using this in a Jakarta EE application, for example.
+ * </p>
+ * The user is responsible for clearing the {@link ThreadLocal}.
*/
@ThreadSafe
-public class ThreadSafeTokenizerME implements Tokenizer {
+public class ThreadSafeTokenizerME implements Tokenizer, AutoCloseable {
private final TokenizerModel model;
- private final ThreadLocal<TokenizerME> tokenizerThreadLocal = new
ThreadLocal<>();
+ private final ThreadLocal<TokenizerME> threadLocal = new ThreadLocal<>();
public ThreadSafeTokenizerME(TokenizerModel model) {
super();
@@ -37,10 +46,10 @@ public class ThreadSafeTokenizerME implements Tokenizer {
}
private TokenizerME getTokenizer() {
- TokenizerME tokenizer = tokenizerThreadLocal.get();
+ TokenizerME tokenizer = threadLocal.get();
if (tokenizer == null) {
tokenizer = new TokenizerME(model);
- tokenizerThreadLocal.set(tokenizer);
+ threadLocal.set(tokenizer);
}
return tokenizer;
}
@@ -58,4 +67,9 @@ public class ThreadSafeTokenizerME implements Tokenizer {
public double[] getProbabilities() {
return getTokenizer().getTokenProbabilities();
}
+
+ @Override
+ public void close() {
+ threadLocal.remove();
+ }
}