You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by be...@apache.org on 2013/06/17 13:53:20 UTC

[1/2] git commit: VYSPER-342: fix charset decoder initialization issue: apply contributed patch (Mikko Multanen)

Updated Branches:
  refs/heads/master 2ba3d39be -> 013be8be8


VYSPER-342: fix charset decoder initialization issue: apply contributed patch (Mikko Multanen)


Project: http://git-wip-us.apache.org/repos/asf/mina-vysper/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-vysper/commit/f477875b
Tree: http://git-wip-us.apache.org/repos/asf/mina-vysper/tree/f477875b
Diff: http://git-wip-us.apache.org/repos/asf/mina-vysper/diff/f477875b

Branch: refs/heads/master
Commit: f477875b0b36968ca7a9440f9c498db6ea7f08a2
Parents: 2ba3d39
Author: Bernd Fondermann <be...@brainlounge.de>
Authored: Mon Jun 17 13:26:24 2013 +0200
Committer: Bernd Fondermann <be...@brainlounge.de>
Committed: Mon Jun 17 13:26:24 2013 +0200

----------------------------------------------------------------------
 .../org/apache/vysper/charset/CharsetUtil.java  | 40 ++++++++++++++++----
 .../apache/vysper/xml/decoder/XMPPDecoder.java  |  4 +-
 .../vysper/xml/sax/impl/XMLTokenizer.java       |  6 +--
 .../impl/AbstractAsyncXMLReaderTestCase.java    |  5 ++-
 .../sax/impl/DefaultAsyncXMLReaderTestCase.java | 12 +++---
 .../xml/sax/impl/ParseElementsTestCase.java     |  6 +--
 .../sax/impl/XMPPContentHandlerTestCase.java    |  2 +-
 .../apache/vysper/xml/sax/perf/PerfRunner.java  |  6 +--
 .../mina/codec/StanzaWriterProtocolEncoder.java |  2 +-
 .../vysper/xmpp/parser/XMLParserUtil.java       |  2 +-
 .../StanzaWriterProtocolEncoderTestCase.java    |  4 +-
 .../xmpp/extension/xep0124/BoshDecoder.java     |  2 +-
 .../vysper/xmpp/extension/xep0124/XMLUtil.java  |  4 +-
 13 files changed, 60 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/nbxml/src/main/java/org/apache/vysper/charset/CharsetUtil.java
----------------------------------------------------------------------
diff --git a/nbxml/src/main/java/org/apache/vysper/charset/CharsetUtil.java b/nbxml/src/main/java/org/apache/vysper/charset/CharsetUtil.java
index 0c95487..48e1da8 100644
--- a/nbxml/src/main/java/org/apache/vysper/charset/CharsetUtil.java
+++ b/nbxml/src/main/java/org/apache/vysper/charset/CharsetUtil.java
@@ -19,6 +19,7 @@
  */
 package org.apache.vysper.charset;
 
+import java.lang.ref.SoftReference;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CharsetEncoder;
@@ -30,13 +31,36 @@ import java.nio.charset.CharsetEncoder;
  */
 public class CharsetUtil {
 
-    /**
-     * Charset decoder for UTF-8
-     */
-    public static final CharsetDecoder UTF8_DECODER = Charset.forName("UTF-8").newDecoder();
+    private static final Charset UTF8 = Charset.forName("UTF-8");
 
-    /**
-     * Charset encoder for UTF-8
-     */
-    public static final CharsetEncoder UTF8_ENCODER = Charset.forName("UTF-8").newEncoder();
+    private static ThreadLocal<CharsetDecoder> decoderCache = new ThreadLocal<CharsetDecoder>();
+    private static ThreadLocal<CharsetEncoder> encoderCache = new ThreadLocal<CharsetEncoder>();
+
+    private static Object getReference(ThreadLocal threadLocal) {
+        SoftReference reference = (SoftReference) threadLocal.get();
+        if (reference != null) return reference.get();
+        return null;
+    }
+
+    private static void setReference(ThreadLocal threadLocal, Object object) {
+        threadLocal.set(new SoftReference(object));
+    }
+
+    public static CharsetEncoder getEncoder() {
+        CharsetEncoder encoder = (CharsetEncoder) getReference(encoderCache);
+        if (encoder == null) {
+            encoder = UTF8.newEncoder();
+            setReference(encoderCache, encoder);
+        }
+        return encoder;
+    }
+
+    public static CharsetDecoder getDecoder() {
+        CharsetDecoder decoder = (CharsetDecoder) getReference(decoderCache);
+        if (decoder == null) {
+            decoder = UTF8.newDecoder();
+            setReference(decoderCache, decoder);
+        }
+        return decoder;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPDecoder.java
----------------------------------------------------------------------
diff --git a/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPDecoder.java b/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPDecoder.java
index b9cbeec..f01be30 100644
--- a/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPDecoder.java
+++ b/nbxml/src/main/java/org/apache/vysper/xml/decoder/XMPPDecoder.java
@@ -102,7 +102,7 @@ public class XMPPDecoder extends CumulativeProtocolDecoder {
         MinaStanzaListener listener = new MinaStanzaListener(out);
         contentHandler.setListener(listener);
 
-        reader.parse(in, CharsetUtil.UTF8_DECODER);
+        reader.parse(in, CharsetUtil.getDecoder());
         
         if (listener.isClosed()) {
             session.close(true);
@@ -112,4 +112,4 @@ public class XMPPDecoder extends CumulativeProtocolDecoder {
             return false;
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/nbxml/src/main/java/org/apache/vysper/xml/sax/impl/XMLTokenizer.java
----------------------------------------------------------------------
diff --git a/nbxml/src/main/java/org/apache/vysper/xml/sax/impl/XMLTokenizer.java b/nbxml/src/main/java/org/apache/vysper/xml/sax/impl/XMLTokenizer.java
index 92aaa9c..37c20ea 100644
--- a/nbxml/src/main/java/org/apache/vysper/xml/sax/impl/XMLTokenizer.java
+++ b/nbxml/src/main/java/org/apache/vysper/xml/sax/impl/XMLTokenizer.java
@@ -103,15 +103,15 @@ public class XMLTokenizer {
                 }
             } else if (state == State.IN_STRING) {
                 if (c == '>') {
-                    emit(CharsetUtil.UTF8_DECODER);
+                    emit(CharsetUtil.getDecoder());
                     emit(c);
                     state = State.START;
                 } else if (isControlChar(c)) {
-                    emit(CharsetUtil.UTF8_DECODER);
+                    emit(CharsetUtil.getDecoder());
                     emit(c);
                     state = State.IN_TAG;
                 } else if (Character.isWhitespace(c)) {
-                    emit(CharsetUtil.UTF8_DECODER);
+                    emit(CharsetUtil.getDecoder());
                     state = State.IN_TAG;
                 } else {
                     buffer.put(c);

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/AbstractAsyncXMLReaderTestCase.java
----------------------------------------------------------------------
diff --git a/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/AbstractAsyncXMLReaderTestCase.java b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/AbstractAsyncXMLReaderTestCase.java
index 3f5f83d..e1dda4d 100644
--- a/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/AbstractAsyncXMLReaderTestCase.java
+++ b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/AbstractAsyncXMLReaderTestCase.java
@@ -1,4 +1,5 @@
 /*
+/*
  *  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
@@ -144,7 +145,7 @@ public abstract class AbstractAsyncXMLReaderTestCase extends TestCase {
         reader.setContentHandler(handler);
         reader.setErrorHandler(handler);
 
-        reader.parse(IoBuffer.wrap(xml.getBytes("UTF-8")), CharsetUtil.UTF8_DECODER);
+        reader.parse(IoBuffer.wrap(xml.getBytes("UTF-8")), CharsetUtil.getDecoder());
 
         return handler.getEvents();
     }
@@ -159,4 +160,4 @@ public abstract class AbstractAsyncXMLReaderTestCase extends TestCase {
             fail("Must not be any more evens, but found one " + events.next().getClass());
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/DefaultAsyncXMLReaderTestCase.java
----------------------------------------------------------------------
diff --git a/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/DefaultAsyncXMLReaderTestCase.java b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/DefaultAsyncXMLReaderTestCase.java
index 894ec31..e411708 100644
--- a/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/DefaultAsyncXMLReaderTestCase.java
+++ b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/DefaultAsyncXMLReaderTestCase.java
@@ -39,11 +39,11 @@ public class DefaultAsyncXMLReaderTestCase extends AbstractAsyncXMLReaderTestCas
         reader.setErrorHandler(handler);
 
         // causes a fatal error
-        reader.parse(IoBuffer.wrap("<root></error>".getBytes("UTF-8")), CharsetUtil.UTF8_DECODER);
+        reader.parse(IoBuffer.wrap("<root></error>".getBytes("UTF-8")), CharsetUtil.getDecoder());
 
         try {
             // not allowed to parse after an error
-            reader.parse(IoBuffer.wrap("<root>".getBytes("UTF-8")), CharsetUtil.UTF8_DECODER);
+            reader.parse(IoBuffer.wrap("<root>".getBytes("UTF-8")), CharsetUtil.getDecoder());
             fail("Must throw SAXException");
         } catch (SAXException e) {
             // OK
@@ -57,11 +57,11 @@ public class DefaultAsyncXMLReaderTestCase extends AbstractAsyncXMLReaderTestCas
         reader.setErrorHandler(handler);
 
         // causes a fatal error
-        reader.parse(IoBuffer.wrap("<root></root>".getBytes("UTF-8")), CharsetUtil.UTF8_DECODER);
+        reader.parse(IoBuffer.wrap("<root></root>".getBytes("UTF-8")), CharsetUtil.getDecoder());
 
         try {
             // not allowed to parse after end of document
-            reader.parse(IoBuffer.wrap("<root>".getBytes("UTF-8")), CharsetUtil.UTF8_DECODER);
+            reader.parse(IoBuffer.wrap("<root>".getBytes("UTF-8")), CharsetUtil.getDecoder());
             fail("Must throw SAXException");
         } catch (SAXException e) {
             // OK
@@ -135,7 +135,7 @@ public class DefaultAsyncXMLReaderTestCase extends AbstractAsyncXMLReaderTestCas
 
     public void testSetFeatureDuringParse() throws Exception {
         DefaultNonBlockingXMLReader reader = new DefaultNonBlockingXMLReader();
-        reader.parse(IoBuffer.wrap("<foo />".getBytes("UTF-8")), CharsetUtil.UTF8_DECODER);
+        reader.parse(IoBuffer.wrap("<foo />".getBytes("UTF-8")), CharsetUtil.getDecoder());
         try {
             reader.setFeature("http://xml.org/sax/features/namespaces", true);
             fail("Must throw SAXNotSupportedException");
@@ -144,4 +144,4 @@ public class DefaultAsyncXMLReaderTestCase extends AbstractAsyncXMLReaderTestCas
         }
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/ParseElementsTestCase.java
----------------------------------------------------------------------
diff --git a/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/ParseElementsTestCase.java b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/ParseElementsTestCase.java
index 87daa39..6d28128 100644
--- a/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/ParseElementsTestCase.java
+++ b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/ParseElementsTestCase.java
@@ -188,8 +188,8 @@ public class ParseElementsTestCase extends AbstractAsyncXMLReaderTestCase {
         System.arraycopy(xml, 0, xml1, 0, 8);
         System.arraycopy(xml, 8, xml2, 0, 8);
 
-        reader.parse(IoBuffer.wrap(xml1), CharsetUtil.UTF8_DECODER);
-        reader.parse(IoBuffer.wrap(xml2), CharsetUtil.UTF8_DECODER);
+        reader.parse(IoBuffer.wrap(xml1), CharsetUtil.getDecoder());
+        reader.parse(IoBuffer.wrap(xml2), CharsetUtil.getDecoder());
 
         Iterator<TestEvent> events = handler.getEvents().iterator();
 
@@ -202,4 +202,4 @@ public class ParseElementsTestCase extends AbstractAsyncXMLReaderTestCase {
         assertNoMoreevents(events);
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/XMPPContentHandlerTestCase.java
----------------------------------------------------------------------
diff --git a/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/XMPPContentHandlerTestCase.java b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/XMPPContentHandlerTestCase.java
index 547c0ef..6a5f453 100644
--- a/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/XMPPContentHandlerTestCase.java
+++ b/nbxml/src/test/java/org/apache/vysper/xml/sax/impl/XMPPContentHandlerTestCase.java
@@ -76,7 +76,7 @@ public class XMPPContentHandlerTestCase extends TestCase {
     }
 
     private void parse(NonBlockingXMLReader reader, String xml) throws Exception {
-        reader.parse(IoBuffer.wrap(xml.getBytes("UTF-8")), CharsetUtil.UTF8_DECODER);
+        reader.parse(IoBuffer.wrap(xml.getBytes("UTF-8")), CharsetUtil.getDecoder());
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/nbxml/src/test/java/org/apache/vysper/xml/sax/perf/PerfRunner.java
----------------------------------------------------------------------
diff --git a/nbxml/src/test/java/org/apache/vysper/xml/sax/perf/PerfRunner.java b/nbxml/src/test/java/org/apache/vysper/xml/sax/perf/PerfRunner.java
index add24dc..5371f3f 100644
--- a/nbxml/src/test/java/org/apache/vysper/xml/sax/perf/PerfRunner.java
+++ b/nbxml/src/test/java/org/apache/vysper/xml/sax/perf/PerfRunner.java
@@ -60,10 +60,10 @@ public class PerfRunner {
 
         StopWatch watch = new StopWatch();
 
-        reader.parse(opening, CharsetUtil.UTF8_DECODER);
+        reader.parse(opening, CharsetUtil.getDecoder());
         for (int i = 0; i < 10000; i++) {
             buffer.position(0);
-            reader.parse(buffer, CharsetUtil.UTF8_DECODER);
+            reader.parse(buffer, CharsetUtil.getDecoder());
         }
         watch.stop();
 
@@ -72,4 +72,4 @@ public class PerfRunner {
 
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/server/core/src/main/java/org/apache/vysper/mina/codec/StanzaWriterProtocolEncoder.java
----------------------------------------------------------------------
diff --git a/server/core/src/main/java/org/apache/vysper/mina/codec/StanzaWriterProtocolEncoder.java b/server/core/src/main/java/org/apache/vysper/mina/codec/StanzaWriterProtocolEncoder.java
index 598188b..f46335c 100644
--- a/server/core/src/main/java/org/apache/vysper/mina/codec/StanzaWriterProtocolEncoder.java
+++ b/server/core/src/main/java/org/apache/vysper/mina/codec/StanzaWriterProtocolEncoder.java
@@ -78,7 +78,7 @@ public class StanzaWriterProtocolEncoder implements ProtocolEncoder {
     }
 
     public CharsetEncoder getSessionEncoder() {
-        return CharsetUtil.UTF8_ENCODER;
+        return CharsetUtil.getEncoder();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/server/core/src/main/java/org/apache/vysper/xmpp/parser/XMLParserUtil.java
----------------------------------------------------------------------
diff --git a/server/core/src/main/java/org/apache/vysper/xmpp/parser/XMLParserUtil.java b/server/core/src/main/java/org/apache/vysper/xmpp/parser/XMLParserUtil.java
index 95eac9a..1487ca0 100644
--- a/server/core/src/main/java/org/apache/vysper/xmpp/parser/XMLParserUtil.java
+++ b/server/core/src/main/java/org/apache/vysper/xmpp/parser/XMLParserUtil.java
@@ -64,7 +64,7 @@ public class XMLParserUtil {
         });
 
         IoBuffer buffer = IoBuffer.wrap(xml.getBytes("UTF-8"));
-        reader.parse(buffer, CharsetUtil.UTF8_DECODER);
+        reader.parse(buffer, CharsetUtil.getDecoder());
 
         if(!documents.isEmpty()) {
             return documents.get(0);

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/server/core/src/test/java/org/apache/vysper/mina/codec/StanzaWriterProtocolEncoderTestCase.java
----------------------------------------------------------------------
diff --git a/server/core/src/test/java/org/apache/vysper/mina/codec/StanzaWriterProtocolEncoderTestCase.java b/server/core/src/test/java/org/apache/vysper/mina/codec/StanzaWriterProtocolEncoderTestCase.java
index ec51ab0..ec61265 100644
--- a/server/core/src/test/java/org/apache/vysper/mina/codec/StanzaWriterProtocolEncoderTestCase.java
+++ b/server/core/src/test/java/org/apache/vysper/mina/codec/StanzaWriterProtocolEncoderTestCase.java
@@ -72,7 +72,7 @@ public class StanzaWriterProtocolEncoderTestCase {
         Mockito.verify(output).write(bufferCaptor.capture());
         
         IoBuffer buffer = bufferCaptor.getValue();
-        String actual = buffer.getString(CharsetUtil.UTF8_DECODER);
+        String actual = buffer.getString(CharsetUtil.getDecoder());
         
         Assert.assertEquals(prolog + opening + content + closing, actual);
     }
@@ -88,7 +88,7 @@ public class StanzaWriterProtocolEncoderTestCase {
         Mockito.verify(output).write(bufferCaptor.capture());
         
         IoBuffer buffer = bufferCaptor.getValue();
-        String actual = buffer.getString(CharsetUtil.UTF8_DECODER);
+        String actual = buffer.getString(CharsetUtil.getDecoder());
         
         Assert.assertEquals(prolog + opening + content, actual);
     }

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshDecoder.java
----------------------------------------------------------------------
diff --git a/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshDecoder.java b/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshDecoder.java
index 4ed27e9..1de678b 100644
--- a/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshDecoder.java
+++ b/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshDecoder.java
@@ -78,7 +78,7 @@ public class BoshDecoder {
             ioBuf.put(buf, 0, i);
         }
         ioBuf.flip();
-        reader.parse(ioBuf, CharsetUtil.UTF8_DECODER);
+        reader.parse(ioBuf, CharsetUtil.getDecoder());
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/f477875b/server/extensions/xep0124-xep0206-bosh/src/test/java/org/apache/vysper/xmpp/extension/xep0124/XMLUtil.java
----------------------------------------------------------------------
diff --git a/server/extensions/xep0124-xep0206-bosh/src/test/java/org/apache/vysper/xmpp/extension/xep0124/XMLUtil.java b/server/extensions/xep0124-xep0206-bosh/src/test/java/org/apache/vysper/xmpp/extension/xep0124/XMLUtil.java
index bfe6c35..45b13ca 100644
--- a/server/extensions/xep0124-xep0206-bosh/src/test/java/org/apache/vysper/xmpp/extension/xep0124/XMLUtil.java
+++ b/server/extensions/xep0124-xep0206-bosh/src/test/java/org/apache/vysper/xmpp/extension/xep0124/XMLUtil.java
@@ -81,7 +81,7 @@ public class XMLUtil implements ContentHandler {
     }
 
     public Stanza parse() throws IOException, SAXException {
-        reader.parse(input, CharsetUtil.UTF8_DECODER);
+        reader.parse(input, CharsetUtil.getDecoder());
         return retStanza;
     }
 
@@ -163,4 +163,4 @@ public class XMLUtil implements ContentHandler {
         // ignore
     }
 
-}
\ No newline at end of file
+}


[2/2] git commit: VYSPER-342: simplify charset codec initialization, prefer singleton approach over thread local

Posted by be...@apache.org.
VYSPER-342: simplify charset codec initialization, prefer singleton approach over thread local


Project: http://git-wip-us.apache.org/repos/asf/mina-vysper/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-vysper/commit/013be8be
Tree: http://git-wip-us.apache.org/repos/asf/mina-vysper/tree/013be8be
Diff: http://git-wip-us.apache.org/repos/asf/mina-vysper/diff/013be8be

Branch: refs/heads/master
Commit: 013be8be8bc384678afc524c053c8584c24827a4
Parents: f477875
Author: Bernd Fondermann <be...@brainlounge.de>
Authored: Mon Jun 17 13:43:19 2013 +0200
Committer: Bernd Fondermann <be...@brainlounge.de>
Committed: Mon Jun 17 13:43:19 2013 +0200

----------------------------------------------------------------------
 .../org/apache/vysper/charset/CharsetUtil.java  | 34 +++++++-------------
 1 file changed, 12 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/013be8be/nbxml/src/main/java/org/apache/vysper/charset/CharsetUtil.java
----------------------------------------------------------------------
diff --git a/nbxml/src/main/java/org/apache/vysper/charset/CharsetUtil.java b/nbxml/src/main/java/org/apache/vysper/charset/CharsetUtil.java
index 48e1da8..3ef49b3 100644
--- a/nbxml/src/main/java/org/apache/vysper/charset/CharsetUtil.java
+++ b/nbxml/src/main/java/org/apache/vysper/charset/CharsetUtil.java
@@ -33,34 +33,24 @@ public class CharsetUtil {
 
     private static final Charset UTF8 = Charset.forName("UTF-8");
 
-    private static ThreadLocal<CharsetDecoder> decoderCache = new ThreadLocal<CharsetDecoder>();
-    private static ThreadLocal<CharsetEncoder> encoderCache = new ThreadLocal<CharsetEncoder>();
+    private static CharsetDecoder decoderCache = null;
+    private static CharsetEncoder encoderCache = null;
 
-    private static Object getReference(ThreadLocal threadLocal) {
-        SoftReference reference = (SoftReference) threadLocal.get();
-        if (reference != null) return reference.get();
-        return null;
-    }
+    public static CharsetDecoder getDecoder() {
+        if (decoderCache != null) return decoderCache;
 
-    private static void setReference(ThreadLocal threadLocal, Object object) {
-        threadLocal.set(new SoftReference(object));
+        synchronized (CharsetUtil.class) {
+            decoderCache = UTF8.newDecoder();
+        }
+        return decoderCache;
     }
 
     public static CharsetEncoder getEncoder() {
-        CharsetEncoder encoder = (CharsetEncoder) getReference(encoderCache);
-        if (encoder == null) {
-            encoder = UTF8.newEncoder();
-            setReference(encoderCache, encoder);
-        }
-        return encoder;
-    }
+        if (encoderCache != null) return encoderCache;
 
-    public static CharsetDecoder getDecoder() {
-        CharsetDecoder decoder = (CharsetDecoder) getReference(decoderCache);
-        if (decoder == null) {
-            decoder = UTF8.newDecoder();
-            setReference(decoderCache, decoder);
+        synchronized (CharsetUtil.class) {
+            encoderCache = UTF8.newEncoder();
         }
-        return decoder;
+        return encoderCache;
     }
 }
\ No newline at end of file