使Java的ByteBuffer线程安全的选项 [英] Options to make Java's ByteBuffer thread safe

查看:256
本文介绍了使Java的ByteBuffer线程安全的选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What options do I have to make a ByteBuffer thread safe? It is known that it is not thread safe as it safes position, limit and some(/all?) methods depend on this internal state.

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

For my purposes it will be sufficient if multiple read-threads are safe, but for other future visitors I would like to know what technics/tricks/traps I need to know to make it completely thread safe.

我的想法:


  • 同步或使用所有方法的ReadWrite锁。可能是最慢的方法(?)

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

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

What other tricks could I use? How would I e.g. implement a "clone bytes on read" with DirectBuffer - is it possible at all? Would probably slicing the full ByteBuffer (ByteBuffer.slice) be involved in one solution?

更新:这是什么意思问题复制( while synchronized)获取指向相同映射字节的新实例

推荐答案

缓冲类可以成为线程安全的...在各个操作正确同步的意义上,等等。但是,API的设计并没有考虑多个线程,所以这可能是浪费时间。

A Buffer class could be made thread-safe ... in the sense that the individual operations were properly synchronized, etcetera. However, the API is not designed with multiple threads in mind, so this this is probably a waste of time.

基本问题是Buffer上的各个操作都是太精细,不能成为同步的单位。应用程序无法在get和put操作级别或翻转,位置等级上进行有意义的同步。一般来说,应用程序需要以原子方式执行这些操作的序列,以便有效地同步。

The basic problem is that the individual operations on a Buffer are too fine-grained to be the unit of synchronization. An application cannot meaningfully synchronize at the level of the get and put operations, or flip, position and so on. Generally speaking, an application needs to perform sequences of these operations atomically in order to synchronize effectively.

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

The second problem is that if you do synchronize at a fine level, this is likely to add significant overheads on the method calls. Since the point of using the Buffer APIs is to do I/O efficiently, this defeats the purpose.

如果你这样做需要同步线程访问共享缓冲区,最好使用外部同步;例如类似这样的事情:

If you do need to synchronize thread access to a shared buffer, it is better to use external synchronization; e.g. something like this:

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

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

Provided all threads that use a given buffer synchronize properly (e.g. using the same lock object), it doesn't matter that the Buffer is not thread-safe. Thread safety is managed externally to the buffer object, and in a more coarse-grained fashion.

正如评论所指出的那样,你也可以使用 ByteBuffer.slice() buffer.asReadOnlyBuffer()为您提供另一个缓冲区,其中现有缓冲区作为后备。但是,在任何一种情况下,javadoc都不保证线程安全。的确,<$ c的 javadocs $ c>缓冲区制作这个一揽子声明:

As comments point out, you could also use ByteBuffer.slice() or buffer.asReadOnlyBuffer() to give you another buffer with the existing one as backing. However, the javadocs do not guarantee thread-safety in either case. Indeed, the javadocs for Buffer make this blanket statement:


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

Buffers are not safe for use by multiple concurrent threads. If a buffer is to be used by more than one thread then access to the buffer should be controlled by appropriate synchronization.

这篇关于使Java的ByteBuffer线程安全的选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆