回调方法中的同步块

时间:2018-08-28 20:39:10

标签: java apache networking apache-mina

我在我的一个项目中使用Apache mina。每次接收到一块数据时,都会调用CumulativeProtocolDecoder的doDecode()。我将这些块连接在一起,直到在字符串末尾得到一个特殊字符。因此,当我收到第一个字符$时开始串联,而当我收到另一个$字符时结束串联。

我想使串联部分同步,以避免任何潜在的非预期串联。

通过用converted()子句封装连接块,我可以使此操作线程安全,但我的问题是,当一个线程正忙于进行连接而另一个线程用新数据调用doDecode()时,新作为同步参数繁忙而提供给doDecode()的参数的信息会丢失,还是会等待并保留参数的缓存直到同步模块再次可用?

@Override
    protected boolean doDecode(IoSession ioSession, IoBuffer ioBuffer, ProtocolDecoderOutput protocolDecoderOutput) throws Exception {
        System.out.println("inside decoder");

        try {
            IoBuffer data = (IoBuffer) ioBuffer;
            // create a byte array to hold the bytes
            byte[] buf = new byte[data.limit()];

            System.out.println("REPSONSE LENGTH: "+ data.limit());
            // pull the bytes out
            data.get(buf);
            // look at the message as a string
            String messageString = new String(buf);

            synchronized (messageString) {
                //do concatenatoin operatoins and other stuff
            }

        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

1 个答案:

答案 0 :(得分:0)

同步局部变量不会有任何用处,因此您可以安全地删除该块。

每个调用doDecode的线程都会有其自己的方法参数副本,因此可以放心在它们之间不更改任何参数。

我猜连接这些块意味着将它们存储在Decoder类的某个成员字段中。

在这种情况下,您可能要在一个字段上进行同步。例如:

private final Object lock = new Object();

@Override
protected boolean doDecode(IoSession ioSession, IoBuffer ioBuffer, ProtocolDecoderOutput protocolDecoderOutput) throws Exception {

    // ...
    synchronized (this.lock) {
        // do concatenation operations and other stuff
    }
    // ...
}

我只是不确定在可能要同时处理请求的框架组件内进行同步是否是一个好习惯。