Я читал статью о Синглтоне в Википедии и наткнулся на этот пример:
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. Я не буду приводить еще один пример, но я надеюсь, что вы поняли идею. Пожалуйста, позвольте мне услышать ваши идеи для более элегантного способа выполнить то, что я пытаюсь сделать. Еще раз спасибо!