简体   繁体   English

为什么此多线程代码被破坏?

[英]Why is this multithreading code broken?

Why is the following multithreading related example code broken? 为什么以下与多线程相关的示例代码被破坏?

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

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

Above two methods are from same class where stringVariable and intVariable are instance variables. 以上两个方法来自同一类,其中stringVariable和intVariable是实例变量。

I thought it will not cause any problem, at least with Thread deadlocks. 我认为这不会造成任何问题,至少与线程死锁有关。 Is there any other reason why this code is broken? 还有其他原因导致此代码损坏吗?

Either you didn't understand the problem, or you are right that this wouldn't cause a deadlock. 您可能不了解问题,或者您认为这不会造成死锁是正确的。

Perhaps he was looking for something more obscure like, 也许他正在寻找更晦涩的东西,

  • you can't lock an int field. 您不能锁定int字段。
  • locking a String object is a very bad idea because you don't know how it is shared. 锁定String对象是一个非常糟糕的主意,因为您不知道它是如何共享的。

But I doubt it. 但我对此表示怀疑。 In any case, he should have clarified the question and your answer because perhaps he might have learnt something, if only how to make the question clearer next time. 无论如何,他应该已经弄清楚了问题和您的答案,因为也许他可能已经学到了一些东西,即使只是下次如何使问题更清晰。

If you, as an interviewer, have a set of screening questions, you should make sure they are covered before you even bring in a candidate. 如果作为面试官,您有一系列筛选问题,则应在招募候选人之前确保将其覆盖。 A questionnaire to give to HR or an agent can be useful. 一份给人力资源或代理人的问卷可能是有用的。 A phone interview is often a good first set. 电话面试通常是个不错的选择。 As a candidate, I sometimes ask for a phone interview, just to see if it is worth my time going to a face to face. 作为候选人,我有时会要求进行电话面试,只是为了看看是否值得我花时间面对面。 (eg if I have serious doubts its worth it) (例如,如果我怀疑是否值得)

Not only are you trying to convince them you are a good fit for them, but they are trying to convince you they are a good fit for you. 您不仅试图说服他们您非常适合他们,而且他们也在试图说服您他们非常适合您。 It appears they failed both technically to explain the problem to you, and how they handled it HR wise, so I would count yourself lucky you didn't waste any more time with them. 看来他们在技术上都无法向您解释问题,以及他们如何合理地解决人力资源问题,因此我很幸运,您不会再浪费时间与他们在一起了。

BTW: Most big companies are diverse and working for one team can be very different to another team. 顺便说一句:大多数大公司都是多元化的,为一个团队工作可能与另一团队大不相同。 It would be unfair to characterise a company based on one experience. 根据一种经验来描述一家公司的特征是不公平的。

The problem is, assuming that both variables have a reference type (otherwise you couldn't synchronize on them), that synchronizing on a variable whose contents could change is broken. 问题是,假设两个变量都具有引用类型(否则您将无法对其进行同步),则在其内容可能会更改的变量上进行同步中断。

The first read of the variable is done without synchronization and whatever reference the thread will see (which could be a completely outdated value) is used to synchronize on, which does not prevent other threads from synchronizing on a different value of that variable as it will be a completely different object. 变量的第一次读取是在没有同步的情况下完成的,并且线程将看到的任何引用(可能是完全过时的值)都将用于同步,这不会阻止其他线程在该变量的其他值上进行同步是一个完全不同的对象。

Since String and Integer are immutable each change of the variable's value implies changing the reference contained in the variable, allowing another thread to enter the synchronized block while the thread performing the change is still inside that block. 由于StringInteger是不可变的,因此变量值的每次更改都意味着更改了变量中包含的引用,从而允许另一个线程进入synchronized块,而执行更改的线程仍位于该块内。

And due to legal reordering of operations it might even appear as if the second thread performs actions inside the synchronized block before the first thread performs the write. 并且由于操作的合法重新排序,它甚至可能看起来像是第二个线程第一个线程执行写操作之前synchronized块内执行了操作。 Just recall that the read of the reference to use for synchronization is not synchronized. 只要回想一下,用于同步的引用的读取是不同步的。 So it's like having no synchronization at all. 因此,就像完全没有同步一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM