9

在下面的代码片段中,将 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();
    }
}
4

5 回答 5

16

对,就是这样。的synchronized性质doThings只会阻止它被同一实例上的多个线程同时调用。该变量在全局x基础上共享,而不是在每个实例基础上共享,因此它是不安全的。

在现实世界中,把它想象成一个有几扇门的浴室——有人可以打开一扇门然后锁上它,但这并不能阻止其他人从另一扇门进来......

于 2011-11-25T11:15:14.950 回答
1

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

于 2011-11-25T11:16:00.383 回答
1

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

于 2011-11-25T11:17:37.207 回答
1

是的。在这种情况下可能会出现竞态条件。当您使方法同步而不是您的变量时。所以根据竞争条件的定义,一个线程将读取变量的值,而同步方法中的另一个线程可以写入它。所以会有一个竞争条件。

于 2011-11-25T11:18:17.650 回答
1

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

于 2011-11-25T11:20:59.920 回答