编码器的编码方法会同时执行吗?我观察到编码方法可能由不同的线程并发。管道定义为:
Channels.pipeline(
idleHandler,
new AmfDecoder<GameEvent>(GameEvent.class),
new AmfEncoder<GameEvent>(),
concurrencyHandler,
new WebHandler());
编码器:
public class AmfEncoder<T extends IAmfEvent> extends OneToOneEncoder{
private final SerializationContext serializationContext = new SerializationContext();
private final Amf3Output amfout = new Amf3Output(serializationContext);
@Override
protected Object encode(ChannelHandlerContext arg0, Channel arg1,
Object arg2) throws Exception {
T e = (T)arg2;
ByteArrayOutputStream byteoutStreamSize = new ByteArrayOutputStream();
amfout.setOutputStream(byteoutStreamSize);
amfout.writeObject(e.getBody());
// byteoutStreamSize has small probability become empty at here, in debug mode I can sure e.getBody() has data
// I thought byteoutStreamSize might be empty by another thread call "amfout.flush()" or "amfout.reset()"
amfout.flush();
//...
amfout.reset();
}
}
Channel.write的调用不仅是属于netty工作线程的线程,还是属于Exeutionhandler中的线程。有一个我自己创建的线程池将调用 Channel.write()。在我将 amfout 和 serializationContext 的 2 个变量移动到 encode() 函数中作为局部变量后,问题就消失了。
Doc 说 ChannelPipeline 是线程安全的,我阅读 netty 3.4.5 发现“添加”、“删除”......操作被锁定,但 sendDownstream 和 sendUpstream 没有锁定。所以如果有不属于worker线程池或ExecutionHandler线程池的线程,并且所有这些线程都调用Channel.write(),解码器和编码器会出现并发问题