为什么下面的多线程相关示例代码被破坏了?
public void method1(){
synchronized(intVariable){
}
synchronized(stringVariable){
}
}
public void method2(){
synchronized(stringVariable){
}
synchronized(intVariable){
}
}
以上两个方法来自同一个类,其中stringVariable和intVariable是实例变量。
我认为这不会导致任何问题,至少在Thread死锁时会出现问题。还有其他原因导致此代码被破坏吗?
答案 0 :(得分:9)
要么你不明白这个问题,要么你说这不会导致死锁。
也许他正在寻找更加模糊的东西,
int
字段。String
对象是一个非常糟糕的主意,因为您不知道它是如何共享的。但我对此表示怀疑。无论如何,他应该澄清问题和你的答案,因为也许他可能已经学会了一些东西,如果只是为了让问题在下次更清楚。
如果作为面试官,你有一套筛选问题,你应该确保在你引入候选人之前就已经覆盖了。向HR或代理人提供的调查问卷可能很有用。电话采访往往是一个很好的第一集。作为候选人,我有时会要求接受电话采访,只是为了看看我是否值得花时间去面对面。 (例如,如果我怀疑它是值得的)
你不仅试图说服他们你很适合他们,而且他们试图说服你他们适合你。看起来他们在技术上都没有向你解释这个问题,以及他们如何处理HR问题,所以我认为你很幸运,你不再浪费时间了。
顺便说一下:大多数大公司都是多元化的,为一个团队工作可能与另一个团队非常不同。根据一种经验来描述公司的特征是不公平的。答案 1 :(得分:0)
问题是,假设两个变量都有一个引用类型(否则你无法对它们进行同步),那么对内容可以改变的变量进行同步就会被破坏。
变量的第一次读取是在没有同步的情况下完成的,线程将看到的任何引用(可能是一个完全过时的值)用于同步,这不会阻止其他线程在该变量的不同值上进行同步因为它将是一个完全不同的对象。
由于String
和Integer
是不可变的,因此变量值的每次更改都意味着更改变量中包含的引用,允许另一个线程在执行更改的线程中输入synchronized
块仍然在那个街区内。
由于操作的合法重新排序,它可能看起来好像第二个线程在第一个线程执行写入之前在synchronized
块内执行操作。请记住,用于同步的参考读取不同步。所以就像没有同步一样。