java中静态方法的同步问题

java中静态方法的同步问题,java,multithreading,synchronization,Java,Multithreading,Synchronization,假设我有一个实用类 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()方法,当操作进入

假设我有一个实用类

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()
方法,当操作进入方法调用时,另一个线程调用相同的方法并传递不同的
s

在这种情况下会发生什么?Java是否锁定静态方法?

除非明确指定,否则不应锁定静态方法。此外,在这种情况下,不会有任何线程安全问题,因为“s”是不可变的,也是方法的局部变量。

这里不需要同步,因为变量s是局部变量


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

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

Java不会锁定静态方法,除非添加关键字
synchronized

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

现在,在您的示例中,在这种特殊情况下不需要同步。这是因为参数是通过副本传递的;因此,对静态方法的多次调用将导致参数的多个副本,每个副本位于各自的堆栈帧中。同样,对
Integer.parseInt
的同时调用将各自创建自己的堆栈帧,并将s值的副本传递到单独的堆栈帧中


现在,如果Integer.parseInt(…)是以一种非常糟糕的方式实现的(在parseInt的执行过程中,它使用了静态的非final成员;那么这将是一个很大的问题。幸运的是,Java库的实现者是比这更好的程序员。

在您给出的示例中,线程之间没有共享数据,也没有修改过的数据。(如果出现线程问题,则必须同时使用这两个选项)


你可以写

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

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

出现此问题的原因是我们接收到具有不同规则和值的XML文件(而且XML没有固定的定义,对同一个服务可以有多个调用同时传递这些XML),我担心调用的结果是否会带来意外的结果。静态方法只是在自己的堆栈上运行的一系列操作码。堆栈不会重叠,所以你很好。@Elite..:如前所述,所有线程都使用自己的堆栈。你知道,局部变量驻留在堆栈中,而实例/类变量驻留在h中eap。