我定义了以下protobuf消息:
message Counts {
repeated int32 counts = 1;
}
作为构建者在线程R
和W
之间共享:
private final Counts.Builder countsBuilder;
线程R
只会从countsBuilder
读取而W
只能写入countsBuilder
。
共享构建器将被读取,写入和(在某些时候)构建和创建。通过网络发送。
AFAIK,并发读取消息很好,但开发人员必须在更高级别同步其他任何内容?那么,我实际上不能同时写入和读取共享构建器吗?
如果这本身并不是线程安全的,我正在考虑使用某种线程安全的Collection<Integer>
,我会用它来读/写,并且会(在某些时候)创建一个全新的消息在通过网络发送之前。或者我错过了什么?
谢谢!
编辑1:我正在使用protobuf 2.4.1和java 6
编辑2:一些术语和拼写修复。
答案 0 :(得分:2)
根据https://developers.google.com/protocol-buffers/docs/reference/cpp,在C ++中不是线程安全的。
而且也不在Java https://developers.google.com/protocol-buffers/docs/reference/java-generated
中我最近遇到了这个问题,并且找到了。这就是它在C ++上所说的
关于线程安全性的说明:
协议缓冲区库中的线程安全性遵循一个简单的规则:除非另有明确说明,否则只要同时在所有线程中将其声明为const,就可以同时使用多个线程中的对象始终是安全的。以声明为const时允许的方式使用)。但是,如果在一个线程中以某种对象无法访问的方式访问该对象,则在同一线程中访问该对象是不安全的。
简单地说,对一个对象的只读访问可以同时在多个线程中进行,但是写访问一次只能在一个线程中进行。
在Java上说过
请注意,构建器不是线程安全的,因此,当需要多个不同的线程来修改单个构建器的内容时,应使用Java同步。
答案 1 :(得分:1)
如果您同步读取和写入,那么您应该没问题:
synchronized (countsBuilder) {
// modify countsBuilder
}
但请记住,您还需要确保在构建消息时没有任何竞争条件;在构建消息之后,不允许编写器线程进行任何写入。