提交 8031ba6a 编写于 作者: 时无两丶 提交者: ken.lj

获取Serializer和Deserializer时,高并发情况下线程block (#1196)

* SerializerFactory 获取Serializer时,锁住整个hashmap,导致整个过程被block

* 单元测试。保证一个class只有一个serializer和deserializer。单线程和多线程测试

* 增加线程数 50 模拟多个线程来获取serializer和deserializer
上级 7cfa2053
......@@ -79,6 +79,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -226,9 +227,9 @@ public class SerializerFactory extends AbstractSerializerFactory {
private ClassLoader _loader;
private Deserializer _hashMapDeserializer;
private Deserializer _arrayListDeserializer;
private HashMap _cachedSerializerMap;
private HashMap _cachedDeserializerMap;
private HashMap _cachedTypeDeserializerMap;
private ConcurrentHashMap _cachedSerializerMap;
private ConcurrentHashMap _cachedDeserializerMap;
private ConcurrentHashMap _cachedTypeDeserializerMap;
private boolean _isAllowNonSerializable;
public SerializerFactory() {
......@@ -293,21 +294,21 @@ public class SerializerFactory extends AbstractSerializerFactory {
* @param cl the class of the object that needs to be serialized.
* @return a serializer object for the serialization.
*/
@Override
public Serializer getSerializer(Class cl)
throws HessianProtocolException {
Serializer serializer;
serializer = (Serializer) _staticSerializerMap.get(cl);
if (serializer != null)
if (serializer != null) {
return serializer;
}
if (_cachedSerializerMap != null) {
synchronized (_cachedSerializerMap) {
serializer = (Serializer) _cachedSerializerMap.get(cl);
}
if (serializer != null)
serializer = (Serializer) _cachedSerializerMap.get(cl);
if (serializer != null) {
return serializer;
}
}
for (int i = 0;
......@@ -346,40 +347,34 @@ public class SerializerFactory extends AbstractSerializerFactory {
}
serializer = _collectionSerializer;
} else if (cl.isArray())
} else if (cl.isArray()) {
serializer = new ArraySerializer();
else if (Throwable.class.isAssignableFrom(cl))
} else if (Throwable.class.isAssignableFrom(cl)) {
serializer = new ThrowableSerializer(cl, getClassLoader());
else if (InputStream.class.isAssignableFrom(cl))
} else if (InputStream.class.isAssignableFrom(cl)) {
serializer = new InputStreamSerializer();
else if (Iterator.class.isAssignableFrom(cl))
} else if (Iterator.class.isAssignableFrom(cl)) {
serializer = IteratorSerializer.create();
else if (Enumeration.class.isAssignableFrom(cl))
} else if (Enumeration.class.isAssignableFrom(cl)) {
serializer = EnumerationSerializer.create();
else if (Calendar.class.isAssignableFrom(cl))
} else if (Calendar.class.isAssignableFrom(cl)) {
serializer = CalendarSerializer.create();
else if (Locale.class.isAssignableFrom(cl))
} else if (Locale.class.isAssignableFrom(cl)) {
serializer = LocaleSerializer.create();
else if (Enum.class.isAssignableFrom(cl))
} else if (Enum.class.isAssignableFrom(cl)) {
serializer = new EnumSerializer(cl);
}
if (serializer == null)
if (serializer == null) {
serializer = getDefaultSerializer(cl);
}
if (_cachedSerializerMap == null)
_cachedSerializerMap = new HashMap(8);
synchronized (_cachedSerializerMap) {
_cachedSerializerMap.put(cl, serializer);
if (_cachedSerializerMap == null) {
_cachedSerializerMap = new ConcurrentHashMap(8);
}
_cachedSerializerMap.put(cl, serializer);
return serializer;
}
......@@ -418,10 +413,7 @@ public class SerializerFactory extends AbstractSerializerFactory {
return deserializer;
if (_cachedDeserializerMap != null) {
synchronized (_cachedDeserializerMap) {
deserializer = (Deserializer) _cachedDeserializerMap.get(cl);
}
deserializer = (Deserializer) _cachedDeserializerMap.get(cl);
if (deserializer != null)
return deserializer;
}
......@@ -462,11 +454,9 @@ public class SerializerFactory extends AbstractSerializerFactory {
deserializer = getDefaultDeserializer(cl);
if (_cachedDeserializerMap == null)
_cachedDeserializerMap = new HashMap(8);
_cachedDeserializerMap = new ConcurrentHashMap(8);
synchronized (_cachedDeserializerMap) {
_cachedDeserializerMap.put(cl, deserializer);
}
_cachedDeserializerMap.put(cl, deserializer);
return deserializer;
}
......@@ -624,9 +614,7 @@ public class SerializerFactory extends AbstractSerializerFactory {
Deserializer deserializer;
if (_cachedTypeDeserializerMap != null) {
synchronized (_cachedTypeDeserializerMap) {
deserializer = (Deserializer) _cachedTypeDeserializerMap.get(type);
}
deserializer = (Deserializer) _cachedTypeDeserializerMap.get(type);
if (deserializer != null)
return deserializer;
......@@ -657,11 +645,9 @@ public class SerializerFactory extends AbstractSerializerFactory {
if (deserializer != null) {
if (_cachedTypeDeserializerMap == null)
_cachedTypeDeserializerMap = new HashMap(8);
_cachedTypeDeserializerMap = new ConcurrentHashMap(8);
synchronized (_cachedTypeDeserializerMap) {
_cachedTypeDeserializerMap.put(type, deserializer);
}
_cachedTypeDeserializerMap.put(type, deserializer);
}
return deserializer;
......
package com.alibaba.com.caucho.hessian.io;
import org.junit.Assert;
import org.junit.Test;
import java.util.concurrent.CountDownLatch;
public class SerializerFactoryTest {
private static final int THREADS = 50;
@Test
public void getSerializer() throws Exception {
final SerializerFactory serializerFactory = new SerializerFactory();
final Class<TestClass> klass = TestClass.class;
Serializer s1 = serializerFactory.getSerializer(klass);
Serializer s2 = serializerFactory.getSerializer(klass);
Assert.assertTrue("several Serializer!", s1 == s2);
}
@Test
public void getSerializerDuplicateThread() throws Exception {
final SerializerFactory serializerFactory = new SerializerFactory();
final Class<TestClass> klass = TestClass.class;
final CountDownLatch countDownLatch = new CountDownLatch(THREADS);
//init into cached map
final Serializer s = serializerFactory.getSerializer(klass);
//get from duplicate thread
for (int i = 0; i < THREADS; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Assert.assertTrue("serveral Serializer!", s == serializerFactory.getSerializer(klass));
} catch (HessianProtocolException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}
}).start();
}
countDownLatch.await();
}
@Test
public void getDeserializer() throws Exception {
final SerializerFactory serializerFactory = new SerializerFactory();
final Class<TestClass> klass = TestClass.class;
Deserializer d1 = serializerFactory.getDeserializer(klass);
Deserializer d2 = serializerFactory.getDeserializer(klass);
Assert.assertTrue("several Deserializer!", d1 == d2);
}
@Test
public void getDeserializerDuplicateThread() throws Exception {
final SerializerFactory serializerFactory = new SerializerFactory();
final Class<TestClass> klass = TestClass.class;
final CountDownLatch countDownLatch = new CountDownLatch(THREADS);
//init into cached map
final Deserializer s = serializerFactory.getDeserializer(klass);
//get from duplicate thread
for (int i = 0; i < THREADS; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Assert.assertTrue("serveral Deserializer!", s == serializerFactory.getDeserializer(klass));
} catch (HessianProtocolException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}
}).start();
}
countDownLatch.await();
}
}
\ No newline at end of file
package com.alibaba.com.caucho.hessian.io;
import java.io.Serializable;
public class TestClass implements Serializable {
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册