Я читал статью о Синглтоне в Википедии и наткнулся на этот пример:
public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
Хотя мне очень нравится, как ведет себя этот синглтон, я не вижу, как его адаптировать для включения аргументов в конструктор. Каков предпочтительный способ сделать это на Java? Придется ли мне сделать что-то подобное?
public class Singleton
{
private static Singleton singleton = null;
private final int x;
private Singleton(int x) {
this.x = x;
}
public synchronized static Singleton getInstance(int x) {
if(singleton == null) singleton = new Singleton(x);
return singleton;
}
}
Благодарность!
Изменить: я думаю, что вызвал бурю споров с моим желанием использовать синглтон. Позвольте мне объяснить свою мотивацию и, надеюсь, кто-нибудь предложит лучшую идею. Я использую сетку вычислений для параллельного выполнения задач. В общем, у меня примерно так:
// AbstractTask implements Serializable
public class Task extends AbstractTask
{
private final ReferenceToReallyBigObject object;
public Task(ReferenceToReallyBigObject object)
{
this.object = object;
}
public void run()
{
// Do some stuff with the object (which is immutable).
}
}
Что происходит, так это то, что даже если я просто передаю ссылку на свои данные всем задачам, когда задачи сериализуются, данные копируются снова и снова. Я хочу поделиться объектом между всеми задачами. Естественно, я мог бы изменить класс так:
// AbstractTask implements Serializable
public class Task extends AbstractTask
{
private static ReferenceToReallyBigObject object = null;
private final String filePath;
public Task(String filePath)
{
this.filePath = filePath;
}
public void run()
{
synchronized(this)
{
if(object == null)
{
ObjectReader reader = new ObjectReader(filePath);
object = reader.read();
}
}
// Do some stuff with the object (which is immutable).
}
}
Как видите, даже здесь у меня есть проблема, заключающаяся в том, что передача другого пути к файлу ничего не значит после передачи первого. Вот почему мне нравится идея магазина, которая была опубликована в ответах. В любом случае, вместо того, чтобы включать логику загрузки файла в метод run, я хотел абстрагировать эту логику в классе Singleton. Я не буду приводить еще один пример, но надеюсь, что вы уловили идею. Пожалуйста, позвольте мне услышать ваши идеи о более элегантном способе выполнения того, что я пытаюсь сделать. Еще раз спасибо!