5

我定义了以下 protobuf msg:

message Counts {
    repeated int32 counts = 1;
}

它在线程之间RW作为构建器共享:

private final Counts.Builder countsBuilder;

线程R只会读取countsBuilder并且W只会写入countsBuilder. 共享构建器将通过网络被读取、写入和(在某些时候)构建和发送。

AFAIK,对消息的并发读取很好,但是开发人员必须在更高级别同步其他任何内容?那么,我实际上不能同时写入和读取共享构建器吗?

如果这本质上不是线程安全的,我正在考虑使用某种线程安全的Collection<Integer>,我将使用它来读取/写入,并将(在某些时候)在通过网络发送之前创建一个全新的消息。还是我错过了什么?

谢谢!

编辑 1:我正在使用 protobuf 2.4.1 和 java 6

编辑 2:一些术语和拼写修复。

4

2 回答 2

2

如果你同步你的读写,你应该没问题:

synchronized (countsBuilder) {
   // modify countsBuilder
}

但请记住,您还需要确保在构建消息时没有任何竞争条件;构建消息后,不允许写入线程进行任何写入。

于 2012-04-22T18:50:53.920 回答
2

根据https://developers.google.com/protocol-buffers/docs/reference/cpp它在 C++ 中不是线程安全的。

而且也不在 java https://developers.google.com/protocol-buffers/docs/reference/java-generated

我最近遇到了这个问题,我发现了这个。这是它在 C++ 上所说的

关于线程安全的说明:

Protocol Buffer 库中的线程安全遵循一个简单的规则:除非另有明确说明,否则从多个线程同时使用一个对象总是安全的,只要该对象在所有线程中都声明为 const(或者,它仅用于如果它被声明为 const 是允许的)。但是,如果一个对象在一个线程中以一种如果它是 const 则不允许的方式被访问,那么同时在任何其他线程中访问该对象是不安全的。

简而言之,对对象的只读访问可以同时在多个线程中进行,但写访问一次只能在单个线程中进行。

在java上说:

请注意,构建器不是线程安全的,因此只要多个不同的线程需要修改单个构建器的内容,就应该使用 Java 同步。

于 2020-05-08T06:39:39.473 回答