Comments (5)
/** * Avoid re applying buffer space every time serialization */ private static final LinkedBuffer BUFFER = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); @Override public byte[] serialize(Object obj) { Class<?> clazz = obj.getClass(); Schema schema = RuntimeSchema.getSchema(clazz); byte[] bytes; try { bytes = ProtostuffIOUtil.toByteArray(obj, schema, BUFFER); } finally { BUFFER.clear(); } return bytes; } @Override public <T> T deserialize(byte[] bytes, Class<T> clazz) { Schema<T> schema = RuntimeSchema.getSchema(clazz); T obj = schema.newMessage(); ProtostuffIOUtil.mergeFrom(bytes, obj, schema); return obj; }
1,其中LinkedBuffer 为静态,在并发情况下其中一个线程执行这个方法BUFFER.clear(),其他的是否会报错
2,Schema schema 这个可以用一个ConcurrentHashMap 存储起来,性能会更好
下面是我修改的代码:private static Map<Class<?>, Schema<?>> schemaMap = new ConcurrentHashMap<>(); private static <T>Schema<T> getSchema(Class<?> clazz) { if (schemaMap.containsKey(clazz)) { return (Schema<T>)schemaMap.get(clazz); } Schema schema = RuntimeSchema.getSchema(clazz); // 双重检查 if (schema != null) { schemaMap.put(clazz, schema); } return schema; } @Override public byte[] serialize(Object object) { Class<?> clazz = object.getClass(); LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); try { Schema schema = getSchema(clazz); return ProtostuffIOUtil.toByteArray(object, schema, buffer); } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } finally { buffer.clear(); } } @Override public <T> T deserialize(byte[] bytes, Class<T> clazz) { Schema<T> schema = getSchema(clazz); T obj = schema.newMessage(); ProtostuffIOUtil.mergeFrom(bytes, obj, schema); return obj; }
老哥 可以提交一个pr么?
from guide-rpc-framework.
/** * Avoid re applying buffer space every time serialization */ private static final LinkedBuffer BUFFER = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); @Override public byte[] serialize(Object obj) { Class<?> clazz = obj.getClass(); Schema schema = RuntimeSchema.getSchema(clazz); byte[] bytes; try { bytes = ProtostuffIOUtil.toByteArray(obj, schema, BUFFER); } finally { BUFFER.clear(); } return bytes; } @Override public <T> T deserialize(byte[] bytes, Class<T> clazz) { Schema<T> schema = RuntimeSchema.getSchema(clazz); T obj = schema.newMessage(); ProtostuffIOUtil.mergeFrom(bytes, obj, schema); return obj; }
1,其中LinkedBuffer 为静态,在并发情况下其中一个线程执行这个方法BUFFER.clear(),其他的是否会报错
2,Schema schema 这个可以用一个ConcurrentHashMap 存储起来,性能会更好
下面是我修改的代码:private static Map<Class<?>, Schema<?>> schemaMap = new ConcurrentHashMap<>(); private static <T>Schema<T> getSchema(Class<?> clazz) { if (schemaMap.containsKey(clazz)) { return (Schema<T>)schemaMap.get(clazz); } Schema schema = RuntimeSchema.getSchema(clazz); // 双重检查 if (schema != null) { schemaMap.put(clazz, schema); } return schema; } @Override public byte[] serialize(Object object) { Class<?> clazz = object.getClass(); LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); try { Schema schema = getSchema(clazz); return ProtostuffIOUtil.toByteArray(object, schema, buffer); } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } finally { buffer.clear(); } } @Override public <T> T deserialize(byte[] bytes, Class<T> clazz) { Schema<T> schema = getSchema(clazz); T obj = schema.newMessage(); ProtostuffIOUtil.mergeFrom(bytes, obj, schema); return obj; }
老哥 可以提交一个pr么?
private static final LinkedBuffer BUFFER = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
guide哥,我想问下,这个buffer不会有线程安全问题么? 我看他内部好像没能保证线程安全
from guide-rpc-framework.
想到了同样的问题,这里肯定是有线程安全问题的
from guide-rpc-framework.
该问题我在压测负载均衡功能时也出现了
- 在多线程场景下,如果只有一个provider,那么所有并发请求都会交由同一个Channel进行处理,而Channel是天然线程安全的,一个Channel只会对应唯一一个线程进行执行,那么使用ProtostuffSerializer进行序列化时不会有线程安全问题
- 当有多个provider时,并发请求进来就会拿到多个Channel,从而多个Channel同时进行序列化,ProtostuffSerializer会出现线程安全的问题,如
Buffer previously used and had not been reset.
对此,我的解决办法如下
public class ProtostuffSerializer implements Serializer {
/**
* Avoid re applying buffer space every time serialization
*
*/
// private static final LinkedBuffer BUFFER = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); 线程不安全
private static final LinkedBuffer[] BUFFERS = new LinkedBuffer[]{LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE),LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE)};
@Override
public byte[] serialize(Object obj) {
System.out.println(Thread.currentThread().getId());
Class<?> clazz = obj.getClass();
Schema schema = RuntimeSchema.getSchema(clazz);
byte[] bytes;
try {
bytes = ProtostuffIOUtil.toByteArray(obj, schema, BUFFERS[(int) (Thread.currentThread().getId()%2)]);
} finally {
BUFFERS[(int) (Thread.currentThread().getId()%2)].clear();
}
return bytes;
}
@Override
public <T> T deserialize(byte[] bytes, Class<T> clazz) {
Schema<T> schema = RuntimeSchema.getSchema(clazz);
T obj = schema.newMessage();
ProtostuffIOUtil.mergeFrom(bytes, obj, schema);
return obj;
}
}
from guide-rpc-framework.
双重检查一样会有线程安全问题,建议修改为computeIfAbsent()方法,会保证本次操作是线程安全的
from guide-rpc-framework.
Related Issues (20)
- 问个问题 HOT 1
- github.javaguide.provider.impl.ZkServiceProviderImpl类中为什么有serviceMap,还需要registeredService这个set去保存接口名? HOT 1
- 无法远程调用无参方法 HOT 2
- 请问如果远程接口有多个实现类怎么办 HOT 1
- 请问自定义RPC协议的设计思路是如何? HOT 1
- 请问服务宕机了,zk能感知到吗 HOT 4
- SPI实现的一点小疑问 HOT 2
- RPC服务调用方法参数传递为Java类对象 HOT 3
- 发现个小问题 HOT 1
- CollectionUtils & StringUtils HOT 1
- 一致性hash中,相同入参无法路由到同一个服务 HOT 3
- 关于服务提供者下线后重新上线,不通过重启客户端无法被服务提供者感知 HOT 1
- 有个问题有人可以解答一下吗? HOT 1
- ExtensionLoader类获取实现类的时候,为什么要加双重锁 HOT 1
- 并发情况下,应该会创建多条连接吧?
- InetAddress.getLocalHost().getHostAddress(); HOT 1
- zookeeper 的 watch 机制导致的问题 HOT 1
- zookeeper版本和curator版本不匹配导致的问题 HOT 1
- 获取rpcServiceName的时候直接用接口名、version、group相加是不是不太好 HOT 1
- 序列化方式Kryo写错了
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from guide-rpc-framework.