【问题标题】:What is the benefit of having synchronized an InputStream?同步 InputStream 有什么好处?
【发布时间】:2017-01-17 22:02:49
【问题描述】:

我最近使用了 Apache Commons-IO 的类 CountingInputStream。它只是通过更新计数器字段来跟踪读取了多少字节。

我注意到它使用synchronized 关键字更新其计数器。我能找到的最佳来源是IO-201,但它没有解释原因。

我在一些地方读到 Apache Commons 代码质量很好,但我现在想知道为什么它们在 InputStream 中有同步方法。我不认为线程安全是流中有用的属性,IO-201 的评论者也不认为。

鉴于我没有同时访问 InputStream,是否有任何正当理由同步其方法?或者是否有一个有效的用例来同时访问不会产生数据垃圾的 InputStream?

【问题讨论】:

  • 我无法理解如何在不获取数据垃圾的情况下同时读取 InputStream。所以我认为并发不能成为synchronized 的动机。但也许这只是我有限的想象力。我不担心,我只是想了解从中学习的动机。
  • 好的,我明白了。另一个线程可能会调用getCount()。如果没有任何同步操作,内存模型就会启动,其他线程可能永远不会看到更新。好的,我很满意。 Volatile 而不是 synchronized 可能也会做同样的工作,对吧?
  • 不,增加volatile 变量不是线程安全的。
  • 多线程并发读取这个流没有意义,read方法是不同步的。 IMO,使用synchronized 的唯一原因是确保计数器的安全发布。 volatile 在这里还不够,因为我们正在做 read-update-writeAtomicLong 可能是一个有效的替代方案。
  • 假设更新计数器是外部同步的,因为它只发生在流的读取操作期间。因此,它受到外部保护,免受竞争条件的影响。另一个线程可能只读取计数器(getCount() 没有任何更新)。因此 volatile 可能足以作为发生前发生的规则,不是吗?实际上这也是IO-201 的作者所声称的:“如果只有一个线程读取流,那么计数字段可能会变为易失性。这将允许其他线程安全地读取计数。”

标签: java inputstream synchronized apache-commons-io


【解决方案1】:

鉴于我没有同时访问 InputStream,是否有任何正当理由同步其方法?

不,您没有正当理由对仅从单个线程访问的对象使用同步方法。话虽如此,您正在使用确实同步的第三方代码来保护可变状态(count 字段),因此除了自己实现之外别无选择。 p>

或者是否有一个有效的用例来同时访问InputStream 不会产生数据垃圾?

InputStream?可能不是。 CountingInputStream?当然...在一个线程中我反复调用CountingInputStream.read() 来消耗流,在另一个线程中我反复调用CountingInputStream.getCount() 来更新我的UI 以显示我已阅读的行数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 2016-03-02
    • 2014-01-21
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    相关资源
    最近更新 更多