【问题标题】:Regarding significance of synchronization关于同步的意义
【发布时间】:2010-11-04 16:09:00
【问题描述】:

这可能是一个愚蠢的问题,但我是 Java 多线程编程的新手。我创建了 4 个线程,然后在它们上调用了 run 方法。在 run 方法中,我使用了一个数组并将值分配给它是索引。我看到每个线程都在维护它自己的数组副本,并且没有线程不安全的行为。我就是想知道,这种情况下使用同步有什么意义?(我还以为是用来控制对共享资源的访问呢,这里的数组不应该是共享数据结构吗?)

【问题讨论】:

    标签: java multithreading synchronized


    【解决方案1】:

    不——如果每个线程都使用自己的数组副本,那么您有四个单独的数组,它们恰好包含相同的数据,但不会发生共享。

    如果您有 一个 数组,并且所有四个线程都在该数组上操作,则共享将是,至少两个线程有​​可能同时使用相同的数据。在这种情况下,您需要同步以确保在任何时候只有其中一个尝试(例如)写入任何特定位置(或者如果一个正在读取而另一个正在写入,则写入是原子完成的,使用read 要么完全在 write 之前发生,要么完全在它之后发生——但不允许两者重叠)。

    【讨论】:

    • 除了糟糕的编程风格之外,在 run 方法中编写所有功能的缺点是什么?如果我在 run 方法中创建和使用所有数据结构,那么每个线程将维护它自己的结构副本,并且不需要同步。
    • 将所有代码放在 run 方法中与将其拆分到多个其他函数中应该不会对同步要求(或缺乏同步要求)产生任何重大影响。
    • 性能方面哪个会更快,共享数据结构还是每个线程都有自己的数据结构?另外,哪种编程风格更好还是取决于上下文?我假设当每个线程维护资源的单独副本时会有内存开销?
    • @simpleguy:这取决于。复制数据需要时间。等待另一个线程也是如此。复制时间是(或多或少)固定的前期成本,而等待是持续成本,取决于不同线程争用相同数据的频率。至于哪个更好,也要看。如果您希望一个线程中的更改对其他线程可见,您只需共享数据即可。如果不是这样,复制数据会简单得多(特别是如果所有线程都以类似方式访问数据)也可以提高速度。
    • 感谢您的回复,非常有见地。
    【解决方案2】:

    只要您绝对确定数组完全不同(此处需要小心,因为根据您所做的操作,可能存在指向同一对象的指针),那么您就不需要同步数组。

    【讨论】:

      【解决方案3】:

      如果您的线程只对自己的私有数据执行操作,则不需要同步。

      顺便说一句,您说您在线程上“调用了 run 方法”;但是,直接调用 Thread.run() 不会在新线程中执行您的逻辑;你会想要调用 Thread.start() 来代替(它在一个单独的线程中内部执行 run() )。

      【讨论】:

      • 是的,我的错。我正在调用 Thread.start(),而后者又调用 run()
      【解决方案4】:

      这取决于您所说的“在运行方法中我正在使用数组”(强调使用)是什么意思?如果您已将数组的引用传递给线程,那么是的,同步将阻止同时访问该数组。但是,如果您在线程中的数组上创建一个实例,那么您有 4 个单独的数组实例并且同步无效。

      【讨论】:

      • 我在 run 方法中创建了一个数组。如果在当前上下文中不需要同步,那么拥有它有什么意义呢?我知道在 run 方法中编写所有功能是不好的编程风格,但主要问题是什么?
      • 在您当前的上下文中,您可以删除同步,因为您有单独的数组副本。如果你想使用同步,你可以在一个公共的地方声明数组(从你产生4个线程的主类或将数组作为另一个类的成员变量,然后将类的实例传递给线程)。您可以声明一个带有同步的方法,然后在其中执行所有重量级活动。只需在运行中调用此方法,因为它是同步的。在任何一个时间点,只有一个线程能够执行它。
      • 这意味着如果我在 run 方法中创建和使用所有数据结构,那么每个线程将维护它自己的结构副本,并且不需要同步?
      • 没错。 run是一个方法,里面声明的变量在方法的作用域内。
      猜你喜欢
      • 2011-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-20
      • 1970-01-01
      • 1970-01-01
      • 2012-07-23
      相关资源
      最近更新 更多