什么更难,同步2个线程或1000个线程?

时间:2010-07-29 12:45:39

标签: java multithreading synchronization

在Paul Tyma的presentation上,我找到了一个面试问题:

  

什么更难,同步2个线程或同步1000个线程?

从我的角度来看,当然同步1000个线程更难,但我当然不能想到“理所当然”的理由。但由于它是面试问题,可能是我错了(面试问题必须棘手,不是吗?)。

14 个答案:

答案 0 :(得分:38)

你可以认为正确同步2个线程的情况实际上比为1000执行它更难,因为如果你有竞争条件,它通常会很快显示1000个线程,但不是只有2个。

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

真正的答案是“以各种方式同步线程,周期。”

答案 1 :(得分:14)

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

现在,同步一千个线程具有良好的性能更加困难。如果我问这个问题,我会寻找答案,提到“雷鸣般的群体问题”,“锁定争用”,“锁定实现可扩展性”,“避免自旋锁”等等。

答案 2 :(得分:4)

在一次采访中,我会说“正好两个线程”是一个非常有用的多线程特例。像饥饿和优先级倒置这样的事情只需要三个线程就可以发生,但只有两个线程优先级倒置和饥饿永远不会发生(好吧,如果一个线程释放并重新获取一个锁而不让另一个线程启动,则会发生饥饿,但是即使在可用时立即抓住锁,也会发生三线程饥饿。从2个线程到3个线程的跳跃比从3个线程变为1,000个更大。

答案 3 :(得分:3)

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

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

您不必添加任何同步代码(只要您正确地执行所有操作)。

答案 4 :(得分:3)

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

答案 5 :(得分:3)

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

话虽这么说,我认为1000个线程程序可能更容易 debug 。脆弱的竞争条件具有更高的发生概率,并且可能更容易复制。如果月亮已满并且您正在度假,则两个线程中的竞争条件可能每5年才出现一次。

答案 6 :(得分:3)

我有两个答案。

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

答案 7 :(得分:2)

采取读写者问题。使用两个线程,您可以使用互斥,并且已完成。有了更多的线程,你必须编写非平凡的代码,因为否则读者无法同时阅读,或者更糟糕的是,他们可能会使编写者挨饿。

但是,良好的同步代码应适用于任意数量的线程。在某些情况下,比如互斥,你可以添加Java的synchronized关键字,对于2个线程和1000个线程一样难。

换句话说,如果你的程序只使用2个线程,你可以利用它并做出更多线程不适用的假设。显然这不是一个好习惯,但它是可能的。

答案 8 :(得分:1)

这是唯一真实答案是“依赖于”的问题之一。在这种情况下,它取决于你正在做什么。

场景可以像前景在显示进度表时等待的单个后台工作线程一样简单。或者它可以产生1000个线程,只需等待它们全部完成,然后再做其他事情。

或者,如果少至2个线程正在访问共享资源,则概念是相同的。您必须非常小心并发问题和锁定策略,无论它是2还是1000.无论多少个线程多于一个,您都无法保证其他东西不会尝试同时读取或写入您所使用的相同资源。

答案 9 :(得分:1)

我同意那些声称“它取决于”的人。如果线程相同,那么2到1000个线程之间就不会有这么大的差异。但是,如果有多个资源需要互斥访问(以Java术语同步),那么死锁的可能性可能会随着线程数量的增加而增加。

答案 10 :(得分:1)

当我查看你的答案时,我发现了一些有趣的想法。我认为,在采访中,这比答案更重要:转换,思想。

答案 11 :(得分:0)

同样难。但是,同步超过2个线程很可能会表现得更好,因为在一个Lock上只有2个Threads,而不是千个,因为资源被锁定,很可能会有更多的开销。

希望有所帮助

答案 12 :(得分:0)

对象是同步的而不是线程。创建同步方法或代码块可防止多个线程同时执行该区域 - 因此,如果有2个,1,000个或1,000,000个线程,则无关紧要。

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

答案 13 :(得分:0)

如果您使用像Scala这样的编程语言,其设计模式为Actors,那么您不必同步任何内容。 http://www.scala-lang.org/node/242

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