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

发布于 2024-12-17 21:02:00 字数 504 浏览 2 评论 0原文

在下面的代码片段中,将 doThings() 方法声明为静态将使该类成为线程安全的。原因是如果启动多个 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();
    }
}

In code snippet below, declaring the doThings() method as static would make the class thread-safe. Is the reason for this that if multiple TestSeven threads are started and since x is a static variable a race condition could occur ?

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();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

请持续率性 2024-12-24 21:02:00

是的,完全正确。 doThings同步本质只会阻止它被同一个实例上的多个线程同时调用。变量x是在全局基础上共享的,而不是在每个实例的基础上共享的,因此它是不安全的。

在现实世界中,可以将其想象为一间有几扇门的浴室 - 有人可以打开一扇门然后将其锁上,但这并不能阻止其他人通过另一扇门进入......

Yes, exactly. The synchronized nature of doThings only stops it from being called by multiple threads concurrently on the same instance. The variable x is shared on a global basis, not on a per-instance basis, therefore it's unsafe.

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...

聊慰 2024-12-24 21:02:00

我认为如果该方法不是静态的,每个 TestSeven 对象将使用自己的锁进行同步 - 因此每个锁将有一个线程,并且它们中的任何一个都不必等待另一个线程。如果该方法被声明为静态,我似乎记得它们锁定了相应的 Class 对象。

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. If the method is declared static, I seem to recall they lock on the corresponding Class object.

半边脸i 2024-12-24 21:02:00

只是补充一点,如果您将方法 doThings 声明为静态,它将在类锁而不是实例锁上同步,因此它将是防弹的。

Just to add that if you declare method doThings static, it will synchronize on the class lock rather than instance lock so then it will be bullet-proof.

榆西 2024-12-24 21:02:00

是的。这里可能会出现竞争条件。当您使方法同步而不是您的变量时。因此,根据竞争条件的定义,一个线程将读取变量的值,而同步方法中的其他线程可以写入它。因此将会存在竞争条件。

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.

岛徒 2024-12-24 21:02:00

您在 this 上同步代码,即在 TestSeven 的该实例上同步代码。 x 是静态的,因此不会被锁定。这就是为什么您可以从不同的实例访问相同的x。为了解锁该属性,您需要在类上进行同步。

You synchronize your code on this, meaning on that instance of TestSeven. x is static, so it will not be locked. That is why, from different instances, you can access the same x. In order to det a lock on that attribute, you'll need to synchronize on the class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文