简体   繁体   English

为什么这段代码不是线程安全的?

[英]Why is this code not thread safe?

In code snippet below, declaring the doThings() method as static would make the class thread-safe. 在下面的代码片段中,将doThings()方法声明为static将使类成为线程安全的。 Is the reason for this that if multiple TestSeven threads are started and since x is a static variable a race condition could occur ? 原因是如果启动了多个TestSeven线程,并且由于x是静态变量,可能会出现竞争条件?

public class TestSeven extends Thread{

    private static int x;

    public synchronized void doThings(){
        int current = x;
        current++;
        x = current;
    }

    public void run(){
        doThings();
    }

    public static void main(String args[]){
        TestSeven t = new TestSeven();
        Thread thread = new Thread(t);
        thread.start();
    }
}

Yes, exactly. 对,就是这样。 The synchronized nature of doThings only stops it from being called by multiple threads concurrently on the same instance . doThingssynchronized特性仅阻止它在同一实例上同时被多个线程调用。 The variable x is shared on a global basis, not on a per-instance basis, therefore it's unsafe. 变量x全局基础上共享,而不是基于每个实例共享,因此它不安全。

In real world terms, think of it as a bathroom with several doors - someone can open one door and then lock it, but that doesn't stop someone else from coming in via a different door... 在现实世界中,把它想象成一个有几个门的浴室 - 有人可以打开一扇门然后将其锁上,但这并不能阻止其他人通过不同的门进入......

I think if the method is not static, each TestSeven object would synchronize using its own lock - so there will be one thread per lock, and none of them will have to wait for another thread. 我认为如果该方法不是静态的,每个TestSeven对象将使用自己的锁进行同步 - 因此每个锁将有一个线程,并且它们都不必等待另一个线程。 If the method is declared static, I seem to recall they lock on the corresponding Class object. 如果方法声明为static,我似乎记得它们锁定了相应的Class对象。

只是要补充一点,如果你声明方法doThings是静态的,它将在类锁上而不是实例锁同步,这样就可以防弹了。

yes. 是。 Race condition could occur in this. 这种情况可能会发生。 As you are making the method synchronized not your variable. 正如您使方法同步而不是您的变量。 So according to the definition of the race condition, one thread will read the value of variable while other in synchronized method can write it. 因此根据竞争条件的定义,一个线程将读取变量的值,而其他同步方法可以写入它。 So a race condition will be there. 所以竞争条件将存在。

You synchronize your code on this , meaning on that instance of TestSeven. 您在同步代码this ,在TestSeven的该实例的意义。 x is static, so it will not be locked. x是静态的,因此不会被锁定。 That is why, from different instances, you can access the same x . 这就是为什么从不同的实例中,您可以访问相同的x In order to det a lock on that attribute, you'll need to synchronize on the class. 为了解除对该属性的锁定,您需要在类上进行同步。

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

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