【问题标题】:Synchronization concerns with a static method in javajava中静态方法的同步问题
【发布时间】:2011-06-22 06:15:54
【问题描述】:

假设我有一个 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() 方法并且操作进入方法调用时,另一个线程调用相同的方法并传递不同的s。 在这种情况下会发生什么? Java 会锁定静态方法吗?

【问题讨论】:

  • 这个问题的原因是我们接收到的XML文件具有不同的规则和值(并且XML没有固定的定义,并且可以对同一个服务进行多次调用同时传递这些XML时间)。

标签: java multithreading synchronization


【解决方案1】:

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

【讨论】:

  • 我不担心Integer.parseInt(),我担心如果调用的结果会带来意想不到的结果。
  • 静态方法只是在自己的堆栈上运行的一系列操作码。堆栈不重叠,所以你很好。
  • @The Elite..:如前所述,所有线程都使用自己的堆栈。而且你知道,局部变量驻留在堆栈中,与驻留在堆中的实例/类变量不同。
【解决方案2】:

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

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

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

现在,如果 Integer.parseInt(...) 以一种非常糟糕的方式实现(它在 parseInt 的执行过程中使用了静态非最终成员;那么就会引起很大的担忧。幸运的是,Java 的实现者库是比这更好的程序员。

【讨论】:

    【解决方案3】:

    在您给出的示例中,线程之间没有共享数据,也没有被修改的数据。 (您必须同时拥有两者才能出现线程问题)


    你可以写

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        这里不需要同步,因为变量 s 是本地变量。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-21
          • 2023-03-25
          • 2011-09-21
          • 2011-02-26
          • 1970-01-01
          相关资源
          最近更新 更多