Java 根据约定,对象应为单例对象,需要同步

Java 根据约定,对象应为单例对象,需要同步,java,static,synchronization,synchronized,synchronized-block,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 } s

我希望通过类引擎只返回我的类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()的客户机需要对format对象(绝对没有状态)执行方法,但会将ByteBuffer传递给该方法(可能会修改此ByteBuffer):

这里/像这样的同步构造是否确保了可序列化性


注:我对Java非常陌生,正如我所读到的,我也可以使方法同步,但我认为检查(result==null)也应该包含在关键部分,所以我决定使用同步(obj)构造。请原谅我,如果这是一个愚蠢的问题,但我想证实我的怀疑

当前,您正在引擎构造函数中创建Format实例,这很可能不是您想要的(您当前的示例将抛出NullPointerException)

第二,您有两个同步问题。第一个问题是格式实例的正确发布。您当前没有这样做。您应该使用类初始化(在类创建时实例化格式实例)或使格式成员不稳定,以便正确发布格式实例


其次,如果format实例具有可变状态,则应使FormatV1方法本身同步。在使用对象之前使调用方在对象上同步是一个非常糟糕的设计。

您创建了引擎类的构造函数来初始化静态变量,而不是使用synchronized创建静态初始值设定项用那种方法

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

实际上,您的方法
getFormat
是基于一个条件的,因此除非始终使用相同的参数(在本例中为
1
),否则它不会返回单例Singleton类不应该有一个公共构造函数。我理解,并且我将始终发送相同的参数。此外,我知道这并不完全是一个Singleton。但我所希望的是,每次BTSEngine收到请求时,都应该返回相同的对象。没有参数可用于静态初始化。如果我使该方法同步..什么关于测试条件..这也需要在一些同步块内..如何实现?我不明白,“在使用对象之前让调用方在对象上同步”。这不是同步(对象)的主要功能吗?@user1071840-你所做的被称为“客户端锁定”,它颠覆了对象封装(例如,FormatV1 impl可以使用标准同步之外的东西来处理线程安全)。为什么需要将测试条件放在同步块内?哦..是..没有两个线程可以进入同步方法并看到不一致的结果..是的,将使用同步方法。
public static synchronized void initFormat(....) {
   if (format == null) {
      ... create it
   } else {
   .... your chocie: throw an exception or do nothing 
   }
}