按照惯例应该是单例的对象所需的同步

时间:2013-09-11 18:09:37

标签: java static synchronization synchronized synchronized-block

我希望我的类只有一个实例,Format1应该通过引擎类返回:

 public final class Engine {

     private static Format format;

     public Engine(final Param1 param1, final Param2 param2) {
         Engine.format = new FormatV1(param1);   // FormatV1 implements Format
     }

     static Format getFormat(int condition) {
         switch(condition) {
            case 1 : return format;
         }
     }
 }

这是否确保只通过getFormat返回一个正确的Format实例?

此外,调用getFormat()的客户端需要对格式对象(绝对没有状态)执行方法,但是将ByteBuffer传递给方法(可能会修改此ByteBuffer):

 class Client 
 {
     public static void main(String[] args) {

          Format obj = Engine.getFormat(1); // some param
          ByteBuffer buffer;                // read data from disk

          synchronized (obj) {

                 long[] result = obj.method(buffer);

                 if (result == null) {
                      // do something
                 }
          }
     }
 }

同步构造在这里/像这样确保可序列化吗?

PS:我对Java很新,尽管我读过,我也可以让方法同步,但我认为检查(结果== null)也应该包含在关键部分,所以我决定使用而是使用synchronized(obj)构造。如果这是一个愚蠢的问题,请原谅我,但我想证实我的疑虑。

2 个答案:

答案 0 :(得分:0)

目前,您正在Engine构造函数中创建Format实例,这很可能不是您想要的(您当前的示例会抛出NullPointerException。

其次,您有2个同步问题。首先是格式实例的正确发布。你现在不这样做。你应该使用类初始化(在类创建时实例化格式实例)或使格式成员易失,以便正确发布格式实例。

其次,如果您的格式实例具有可变状态,那么您应该使FormatV1方法本身同步。在使用它之前让调用者在对象上进行同步是一个非常糟糕的设计。

答案 1 :(得分:0)

您创建了Engine类的构造函数来初始化静态变量,而是创建一个静态初始化程序,在该方法上使用synchronized

public static synchronized void initFormat(....) {
   if (format == null) {
      ... create it
   } else {
   .... your chocie: throw an exception or do nothing 
   }
}