同步涉及java中的静态方法

时间:2011-06-22 06:15:54

标签: java multithreading synchronization

假设我有一个Utility类,

public class Utility {

    private Utility() {} //Don't worry, just doing this as guarantee.

    public static int stringToInt(String s) {
        return Integer.parseInt(s);
    }
};

现在,假设在多线程应用程序中,线程调用Utility.stringToInt()方法和,而操作进入方法调用,另一个线程调用相同的方法传递不同的{{1 }}。 在这种情况下会发生什么? Java会锁定静态方法吗?

5 个答案:

答案 0 :(得分:10)

这里没有问题。每个线程都将使用自己的堆栈,因此不同的s之间没有冲突点。 Integer.parseInt()是线程安全的,因为它只使用局部变量。

答案 1 :(得分:3)

除非您添加关键字synchronized

,否则Java不会锁定静态方法

请注意,当您锁定静态方法时,您将获取实现该方法的Class对象的Mutex,因此在静态方法上进行同步将阻止其他线程进入任何其他“同步”静态方法。

现在,在您的示例中,您不需要在此特定情况下进行同步。那是因为参数是通过复制传递的;因此,多次调用静态方法将导致参数的多个副本,每个副本都在自己的堆栈帧中。同样,对Integer.parseInt(s)的同时调用将分别创建自己的堆栈帧,并将s值的副本传递到单独的堆栈帧中。

现在,如果Integer.parseInt(...)以非常糟糕的方式实现(它在parseInt执行期间使用静态非final成员;那么就会有一个值得关注的原因。幸运的是,Java的实现者图书馆是比这更好的程序员。

答案 2 :(得分:1)

在您给出的示例中,线程之间没有共享数据,并且没有修改的数据。 (你必须同时拥有一个线程问题)


你可以写

public enum Utility {
    ; // no instances

    public synchronized static int stringToInt(String s) {
        // does something which needs to be synchronised.
    }
}

这实际上与

相同
public enum Utility {
    ; // no instances

    public static int stringToInt(String s) {
        synchronized(Utility.class) {
            // does something which needs to be synchronised.
        }
    }
}

但是,它不会将该方法标记为已同步,除非您正在访问可以修改的共享数据,否则不需要同步。

答案 3 :(得分:0)

除非明确指明,否则不应该。此外,在这种情况下,不存在任何线程安全问题,因为“s”是不可变的,也是方法的本地。

答案 4 :(得分:0)

您不需要同步,因为变量 s 是本地的。

只有当多个线程共享资源时才需要担心,例如如果 s 是静态字段,那么你必须考虑多线程。