0

为什么下面的多线程相关示例代码被破坏了?

public void method1(){
    synchronized(intVariable){
    }
    synchronized(stringVariable){
    }
}

public void method2(){
    synchronized(stringVariable){
     }
    synchronized(intVariable){
     }
}

以上两个方法来自同一个类,其中 stringVariable 和 intVariable 是实例变量。

我认为这不会引起任何问题,至少在线程死锁的情况下。这段代码被破坏还有其他原因吗?

4

2 回答 2

9

要么你不理解这个问题,要么你是对的,这不会导致死锁。

也许他在寻找更模糊的东西,比如,

  • 你不能锁定一个int字段。
  • 锁定一个String对象是一个非常糟糕的主意,因为您不知道它是如何共享的。

但我对此表示怀疑。无论如何,他应该已经澄清了问题和您的答案,因为也许他可能学到了一些东西,只要下次如何使问题更清楚。

作为面试官,如果你有一组筛选问题,你应该确保在你引入候选人之前就已经涵盖了这些问题。提供给 HR 或代理的问卷可能很有用。电话面试通常是一个很好的第一组。作为应聘者,我有时会要求进行电话面试,只是想看看是否值得我花时间去面对面。(例如,如果我严重怀疑它是否值得)

你不仅要让他们相信你很适合他们,而且他们也在努力让你相信他们很适合你。看来他们在技术上未能向您解释问题,以及他们如何明智地处理人力资源问题,所以我认为您自己很幸运,您没有再浪费时间与他们在一起。

顺便说一句:大多数大公司都是多元化的,为一个团队工作可能与另一个团队非常不同。根据一种经验来描述一家公司是不公平的。

于 2013-10-06T09:11:30.363 回答
0

问题是,假设两个变量都具有引用类型(否则您无法在它们上同步),那么在其内容可能更改的变量上的同步就会被破坏。

变量的第一次读取是在没有同步的情况下完成的,线程将看到的任何引用(可能是一个完全过时的值)都用于同步,这不会阻止其他线程在该变量的不同值上同步,因为它将成为一个完全不同的对象。

由于StringInteger是不可变的,因此变量值的每次更改都意味着更改包含在变量中的引用,从而允许另一个线程进入synchronized块,而执行更改的线程仍在该块内。

而且由于操作的合法重新排序,它甚至可能看起来好像第二个线程在第一个线程执行写入之前synchronized在块内执行了操作。请记住,用于同步的引用的读取是不同步的。所以这就像根本没有同步。

于 2013-10-09T08:04:19.673 回答