多线程环境中的字节缓冲区[重复]

Posted

技术标签:

【中文标题】多线程环境中的字节缓冲区[重复]【英文标题】:Bytebuffer in multithreaded environment [duplicate] 【发布时间】:2019-01-04 08:07:21 【问题描述】:
class RequestMessage

public byte[] getMsgAsBytes() throws UnsupportedEncodingException
        ByteBuffer reqBuffer = ByteBuffer.allocate(PAYLOAD_SZ);
        reqBuffer.put(xxx);
        reqBuffer.putInt(xxx);
        reqBuffer.put(xxx);
        reqBuffer.position(0);
        return reqBuffer.array();
    

RequestMessage 类随后被单例以下列方式使用(read-only)。单例将被多个线程串联访问。

private void sendRequest(...) throws Exception 
        RequestMessage reqMessage = new RequestMessage( );
        gateway.sendAsyncMessage(...., reqMessage.getMsgAsBytes());


字节缓冲区的这种用法是线程安全的吗? 我们确实看到数组内容偶尔损坏,需要确定原因。

【问题讨论】:

这取决于xxx-values 是什么。它们可以变异吗?他们来自哪里? 如果 bytebuffer 是按图示分配的(在getMsgAsBytes() 方法中),那么每个线程都会有它自己的 bytebuffer,所以它永远不会在线程之间共享。 正如托马斯所说,您在这里向我们展示的东西没有问题。您没有向我们展示的是 xxx 值的来源 - 如果它们来自某个共享来源,那可能是个问题。 【参考方案1】:

如果xxxes 是RequestMessage 的实例字段,它是线程安全的:因为RequestMessageByteBuffer 都是局部变量,它们不能被另一个线程更改。

【讨论】:

正如@Hulk 在 cmets 中提到的,如果 xxx 来自共享资源会怎样。在这种情况下,我们不能确定 RequestMessage 类是线程安全的。 @YugSingh 是的。我假设他们不是。 嗯嗯嗯嗯嗯。你知道他们对假设的看法。【参考方案2】:

观察到的损坏包括什么?

如果这些 xxx 是 RequestMessage 的实例字段并且它们是不可变的(意味着没有设置器并且它们的值在构造函数调用时设置和固定)并且构成 xxx 的任何对象的状态本身也是不可变的那么事物应该是不可破坏的。

否则无法避免偶尔的损坏,因为如果系统的其他部分认为它应该这样做,则无法避免将对象传递给其他线程。并且在您读取该状态时,无法避免状态以不可预知的方式和/或顺序发生突变。

【讨论】:

以上是关于多线程环境中的字节缓冲区[重复]的主要内容,如果未能解决你的问题,请参考以下文章

字节输入流

C# 中如何做多线程的串口通讯?

linux下c语言实现多线程文件复制

Java基础面试题

将字节 [] 写入 OutputStream 时添加缓冲区 [重复]

C++中的多线程实现