代码之家  ›  专栏  ›  技术社区  ›  nanda

同步2个线程或1000个线程有什么困难?

  •  11
  • nanda  · 技术社区  · 15 年前

    论Paul Tyma presentation ,我发现了一个面试问题:

    同步2个线程或同步1000个线程有什么困难?

    从我的角度来看,同步1000个线程当然比较困难,但是除了“当然”之外,我想不出一个好的理由。但既然是 面试问题 ,可能是我错了(面试问题一定很棘手,不是吗?).

    14 回复  |  直到 15 年前
        1
  •  14
  •   Borealid    15 年前

    同步一千个线程和同步两个线程一样简单:只需锁定对所有重要数据的访问。

    现在,同步一千个线程 性能良好 更难。如果我问这个问题,我会寻找“雷鸣般的集群问题”、“锁争用”、“锁实现可伸缩性”、“避免旋转锁”等答案。

        2
  •  38
  •   Michael Borgwardt    15 年前

    您可能会认为,正确同步2个线程实际上比1000个线程要困难,因为如果您有争用条件,1000个线程通常会很快出现这种情况,但只有2个线程不会出现这种情况。

    但另一方面,在不遇到锁争用问题的情况下同步1000个线程要比只有2个线程困难得多。

    真正的答案是“同步线程在各个方面都很困难,时间段”。

        3
  •  4
  •   supercat    15 年前

    在一次采访中,我会说“恰好两个线程”是多线程的一个非常有用的特殊情况。像饥饿和优先级反转这样的事情可以在只有三个线程的情况下发生,但是只有两个线程的情况下,优先级反转和饥饿永远不会发生(好吧,如果一个线程在不让另一个线程启动的情况下释放并重新获取一个锁,可能会发生饥饿,但是如果有三个线程,即使锁被抓取,也可能发生饥饿。有空的时候)。从2个线程跳到3个线程比从3个线程跳到1000个线程要大。

        4
  •  3
  •   Justin Niessner    15 年前

    为什么同步1000个线程比同步2个线程更困难?

    唯一要添加的代码是产生额外的线程。

    您不必添加任何同步代码(只要您做的一切都正确)。

        5
  •  3
  •   Sergii Pozharov    15 年前

    我认为答案是,在两个线程同步之后,其他998也将同步

        6
  •  3
  •   jdizzle    15 年前

    这取决于“更容易”的含义。设计/锁定机制的复杂性大致相同。

    也就是说,我认为1000个线程程序可能更容易 调试 . 易受攻击的种族条件具有更高的发生概率,可能更容易复制。如果月亮是圆的,而你正在度假,两条线中的比赛条件可能每5年出现一次。

        7
  •  3
  •   emory    15 年前

    我有两个答案。

    1. 案例1:利用现有资源: 同步2个线程与同步1000个线程的难度相同,因为现有线程是为同步任意数量的线程而创建的。
    2. 案例2:从头开始实施 很明显,如果必须从头开始实现同步系统,那么构建2线程系统就更容易了。
        8
  •  2
  •   sdcvvc    15 年前

    以读写问题为例。有了两个线程,就可以使用互斥了。有了更多的线程,您就必须编写非琐碎的代码,因为否则读者就不能同时阅读,或者更糟,他们可能会使编写者挨饿。

    但是,好的同步代码应该适用于任何数量的线程。在某些情况下,比如互斥,可以添加Java的同步关键字,它对于2个线程来说是困难的,如1000。

    换句话说,如果您的程序只使用2个线程,那么您可以利用这一点,并假设在更多的线程中这是不正确的。显然这不是一个好的实践,但它是可能的。

        9
  •  1
  •   Quick Joe Smith    15 年前

    这是唯一真正的答案是“视情况而定”的问题之一。在这种情况下,这取决于你对他们做了什么。

    一个场景可以像单个后台工作线程一样简单,前台在显示进度表时等待该线程。或者它可以生成1000个线程,并在执行其他操作之前简单地等待它们全部完成。

    或者,如果只有2个线程在访问共享资源,那么这些概念是相同的。无论是2还是1000,您都必须非常小心并发性问题和锁定策略。不管多个线程有多少个,都不能保证其他线程不会同时读写您所处的同一资源。

        10
  •  1
  •   Schedler    15 年前

    我同意那些说“视情况而定”的说法。如果螺纹是相同的,那么2到1000个螺纹之间就不会有这么大的差别。然而,如果存在需要互斥访问的多个资源(以Java术语同步),那么死锁的可能性可能随着线程数量的增加而增加。

        11
  •  1
  •   ern0    15 年前

    当我浏览你的答案时,我发现了几个有趣的难题。我认为,在采访中,这比答案更重要:转变,挑战。

        12
  •  0
  •   fasseg    15 年前

    这同样困难。但是,两个线程之间的同步很可能执行得更好,因为只有两个线程在一个锁上发生冲突,而不是一千个线程,因为锁定的资源很可能会增加开销。

    希望有帮助

        13
  •  0
  •   Tarski    15 年前

    对象是同步的,而不是线程。创建一个同步的方法或代码块可以防止多个线程同时执行该区域-因此,如果有2个、1000个或1000000个线程并不重要。

    在性能方面,如果希望在线程数增加一倍时实现两倍并行(半执行时间),则任何同步区域在性能方面都将成为瓶颈,因为它本质上是无法并行的串行代码。

        14
  •  0
  •   Joe Stein    15 年前

    如果您使用类似scala的编程语言和参与者的设计模式,那么您不必同步任何东西。 http://www.scala-lang.org/node/242

    Java中的另一个选项是使用比较和交换/设置的机制。 http://en.wikipedia.org/wiki/Compare-and-swap 因此,您不必同步任何线程,因为它们是您正在比较和读取的原子变量(非阻塞),并且只在写入时阻塞/等待,这可以根据您的解决方案获得一些巨大的性能提升。