使Java的ByteBuffer线程安全的选项

我有什么选择使ByteBuffer线程安全? 众所周知,它不是线程安全的,因为它保护位置,限制和一些(/ all?)方法依赖于这种内部状态。

对于我的目的,如果多个读线程是安全的就足够了,但对于其他未来的访问者,我想知道我需要知道哪些技术/技巧/陷阱才能使其完全线程安全。

我的想法:

  • 为所有方法同步或使用ReadWrite锁。 可能是最慢的方法(?)
  • Subclassing ByteBuffer并避免持久化线程绑定状态,如位置等。并相应地为所有需要使用内部状态的方法抛出exception。 这将是紧要关头。 但是有陷阱吗? (除了我必须将直接映射的内存读入堆内存…)

我可以使用哪些其他技巧? 我如何使用DirectBuffer实现“读取时克隆字节” – 它有可能吗? 可能会将完整的ByteBuffer(ByteBuffer.slice)切成一个解决方案吗?

更新 :此问题的含义是“重复(同步)以获取指向相同映射字节的新实例”

可以使Buffer类成为线程安全的…在某些意义上,各个操作是正确同步的,等等。 但是,API的设计并未考虑多个线程,因此这可能是浪费时间。

基本问题是Buffer上的各个操作太细粒度而不是同步单元。 应用程序无法在get和put操作级别或翻转,位置等级上进行有意义的同步。 一般而言,应用程序需要以primefaces方式执行这些操作的序列以便有效地同步。

第二个问题是,如果您在精确级别进行同步,则可能会在方法调用上增加大量开销。 由于使用Buffer API的目的是为了有效地进行I / O,这就失败了。


如果确实需要将线程访问同步到共享缓冲区,最好使用外部同步; 例如这样的事情:

synchronized (someLock) { buffer.getByte(); buffer.getLong(); ... } 

如果使用给定缓冲区的所有线程都正确同步(例如,使用相同的锁对象),则缓冲区不是线程安全的并不重要。 线程安全性在缓冲区对象外部进行管理,并且采用更粗粒度的方式。


正如评论所指出的那样,您也可以使用ByteBuffer.slice()buffer.asReadOnlyBuffer()为您提供另一个缓冲区,并将现有缓冲区作为支持。 但是,在任何一种情况下,javadoc都不保证线程安全。 实际上, Buffer的javadocs做了这个一揽子声明:

多个并发线程使用缓冲区是不安全的。 如果要由多个线程使用缓冲区,则应通过适当的同步来控制对缓冲区的访问。