简体   繁体   English

将具有静态属性的单例更改为多例

[英]Change a Singleton with static properties into a Multiton

I have the following Singleton class 我有以下单例课程

public class TestFileEngine {
    private static int counter = 0;
    private static List<GeneratedFile> generatedFileList;
    private static Optional<TestFileEngine> engine = Optional.empty();

    private TestFileEngine() {
        generatedFileList = Collections.synchronizedList(new ArrayList<>());
    }

    public static synchronized TestFileEngine getInstance() {
        if (!engine.isPresent()) {
            engine = Optional.of(new TestFileEngine());
        }

        return ruEngine.get();
    }

    public synchronized void generateFile() {
        counter++;
        String timestamp = LocalDateTime.now().toString();
        String content = "";//insert random content generation
        GeneratedFile gf = new GeneratedFile(counter + ".txt", timestamp, content);
        generatedFileList.add(gf);
        System.out.println("Generated file " + counter + ".txt");
    }

    public GeneratedFile findFileByName(String filename) {
        for (GeneratedFile file : generatedFileList){
           if(file.getFileName().equals(filename)){
               return file;
           }
        }
        return null;
    }
}

Now I want to have two separate engines (and possibly more in the future), for tracking purpose and I stumbled upon the multiton pattern, still using the lazy implementation. 现在,我想拥有两个单独的引擎(将来可能还会增加),用于跟踪目的,我偶然使用了懒惰的实现,偶然发现了multiton模式。 So I will change the following: 因此,我将更改以下内容:

//Getting rid of Optional, as it can get funky with Maps
private static final Map<String, TestFileEngine> _engines = new HashMap<String, TestFileEngine>();

public static synchronized TestFileEngine getInstance(String key) {
    if (_engines.get(key) == null) {
        _engines.put(key, new TestFileEngine());
        System.out.println("Create engine " + key);
    }else {
        System.out.println("Using engine " + key);
    }

    return _engines.get(key);
}

I want to be sure that each of the engines has its separate counter and file list. 我想确保每个引擎都有其单独的计数器和文件列表。 However after I ran the following code, it seems they share counter and list: 但是,在我运行以下代码之后,似乎它们共享计数器和列表:

TestFileEngine.getInstance("http").generateFile();
TestFileEngine.getInstance("http").generateFile();
TestFileEngine.getInstance("http").generateFile();
TestFileEngine.getInstance("ftp").generateFile();
TestFileEngine.getInstance("ftp").generateFile();

System.out.println(TestFileEngine.getInstance("http").findFileByName("4.txt").getFileName());
System.out.println(TestFileEngine.getInstance("ftp").findFileByName("2.txt"));

Console: 安慰:

Create engine http
Generated file 1.txt
Using engine http
Generated file 2.txt
Using engine http
Generated file 3.txt
Create engine ftp
Generated file 4.txt
Using engine ftp
Generated file 5.txt
Using engine http
4.txt
Using engine ftp
null

What should I do to the counter and generatedFileList fields so that each TestFileEngine created from the Multiton is completely separated? 我应如何处理countergeneratedFileList字段,以使从TestFileEngine创建的每个TestFileEngine完全分离?

Actually you declare the 3 fields of the class with the static modifier : 实际上,您可以使用static修饰符声明该类的3个字段:

private static int counter = 0;
private static List<GeneratedFile> generatedFileList;
private static final Map<String, TestFileEngine> _engines = new HashMap<String, TestFileEngine>();

static fields are shared among all instances of the current class. static字段在当前类的所有实例之间共享。
You want that for engines field. 您想要engines领域。
But you don't want that for counter and generatedFileList fields that have to be attached to a specific instance of TestFileEngine . 但是,您不希望将必须附加到TestFileEngine的特定实例的countergeneratedFileList字段用作附加字段。 So make them instance fields instead of static . 因此,使它们成为实例字段而不是static

As a side note, int fields are by default valued to 0 and you should avoid _ to prefix your variables that doesn't make part of the naming conventions. 附带说明一下, int字段默认情况下的值为0并且您应避免使用_前缀不属于命名约定的变量。
So you could write : 所以你可以这样写:

private int counter;
private List<GeneratedFile> generatedFileList;
private static final Map<String, TestFileEngine> engines = new HashMap<String, TestFileEngine>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM