【问题标题】:Synchronizing to an object to be instantiated同步到要实例化的对象
【发布时间】:2011-09-22 15:09:13
【问题描述】:

此代码是否存在任何同步/引用问题?

(假设myStrings 已经实例化。)

MySynch.java:

public class MySynch
{
    public static String[] myStrings = new String[10];

    public static void updateStrings()
    {
        synchronized (myStrings)
        {
            myStrings = new String[10]; // Safe?

            myStrings[0] = something[0];
            myStrings[1] = somethingElse[4];
        }
    }
}

对象数组myStrings 可以被多个线程读取,并且有一个线程通过运行updateStrings() 来更新(写入)它。从中读取的线程也将使用 synchronized (myStrings) 块来读取它,当然,为了安全起见。

锁定数组并在内部锁定它的synchronized 块(如上)再次实例化它是否存在问题?

【问题讨论】:

    标签: java multithreading concurrency locking synchronized-block


    【解决方案1】:

    有一个同步问题:当 myStrings 设置为一个新实例,并且紧接着第二个线程正在执行该方法时,第二个线程将同步 myStrings 的第二个实例。

    您应该在类或任何其他静态最终对象上同步

    synchronized(MySynch.class) {
        ...
    }
    

    【讨论】:

    • 谢谢,听起来不错。我还需要做些什么才能使其正常工作,例如将该类声明为最终类(如果可以的话),或者其他什么?
    • 没有。类上没有什么可做的,可以将其用作同步监视器。
    • 请注意,您可以声明一个最终类。但这意味着它不能扩展。
    【解决方案2】:

    我能看到的唯一问题是有可能在数组被正确实例化之前执行读取。

    【讨论】:

    • 哦,假设myStrings在程序开始时已经被实例化了。
    • @panic,您使用 static 修饰符有什么原因吗?
    • 是的,我不会创建类本身的实例,它基本上是一个常用方法库等等。
    • @panic,通常实用程序类是无状态的。也许你应该把它变成一个单例?
    • 我编辑了程序以防止在正确实例化数组之前执行读取的可能性,但没有什么可以阻止其他代码将数组设置为 null。
    【解决方案3】:

    你会得到不一致的 myStrings 值,最好有两个同步块或方法,一个用于更新,另一个用于获取类锁并将你的 myStrings 私有。

    // update
    synchronized (YourClass.class) {
        // update
    }
    
    // get
    synchronized (YourClass.class) {
        // get
    }
    

    【讨论】:

      【解决方案4】:

      清洁工,IMO。

      public class MySynch {
      private static AtomicReference<String[]> myStrings = new AtomicReference<String[]>(
              new String[0]);
      
      public static void updateStrings() {
          String[] tmp = new String[2];
                  ....
          myStrings.set(tmp);
      
      }
      
      public static String[] getStrings() {
          return myStrings.get();
      }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多