Tem como pegar a instancia de uma classe que já está rodando?
Por que no meu aplicativo eu só posso inicializa uma classe uma única vez e queria saber também se tem como “matar” esta instancia que esta rodando?
Vc pode passar null para todas as referências daquele objeto e esperar o garbage collector.
Entretanto acho q no seu caso tem alguma coisa mal explicada…
Ola,
Dê uma olhada no padrão singleton… dae fica facil matar ela.
Hã? É justamente o contrário!
O Singleton não funciona bem em Java. É difícil garantir que o objeto seja realmente singleton.
E, graças ao Garbage Collector, é praticamente impossível matar um Singleton em Java.
Concordo ficou meio confuso…
O aplicativo funciona desta maneira, o usuário pode inicializar um processo, que no meu caso é esta classe que só pode ser inicializada uma única vez, esta classe fica rodando direto, não para, se o usuário fechar o browser e abrir novamente o aplicativo tem que indicar que a classe ainda está rodando.
O usuário também tem a possibilidade de parar o processo, por isso eu preciso pegar a instância da classe.
Hã? É justamente o contrário!
O Singleton não funciona bem em Java. É difícil garantir que o objeto seja realmente singleton.
E, graças ao Garbage Collector, é praticamente impossível matar um Singleton em Java.[/quote]
Haaa… concordo não…
public class Exemplo{
private static Exemplo instance;
private String nome;
public static Exemplo getInstance(){
if(instance == null){
instance = new Exemplo();
}
return instance;
}
public static void killMyself(){
instance = null;
}
public void setNome(String nome){
this.nome = nome;
}
public String getNome(){
return nome;
}
Se vc usar um analisador de memoria vera que esta classe saira quando se chamar o killMyself dela. e depois do GC…
[quote=Jedi_FeniX]Concordo ficou meio confuso…
O aplicativo funciona desta maneira, o usuário pode inicializar um processo, que no meu caso é esta classe que só pode ser inicializada uma única vez, esta classe fica rodando direto, não para, se o usuário fechar o browser e abrir novamente o aplicativo tem que indicar que a classe ainda está rodando.
O usuário também tem a possibilidade de parar o processo, por isso eu preciso pegar a instância da classe.[/quote]
Pois é, pra min se isto não é um singleton…
Dá uma olhada no que é este singleton: http://pt.wikipedia.org/wiki/Singleton
Este seu aplicativo seria o que exatamente? Uma thread? Um aplicativo desktop stand-alone? Um aplicativo desktop cliente-servidor?
Você fala dessa classe como se ela fosse algo dissociado do seu aplicativo. Porque diz “quando fechar” e “quando iniciar o aplicativo”, e em seguida diz que independente de fechar ou reiniciar o aplicativo a classe deve ficar “rodando”…
Daria pra resolver relativamente fácil adotando a arquitetura cliente-servidor, mas não sei exatamente qual é a natureza da aplicação…
Abraço…
Singleton em Java é um pepino porque pode sempre ser burlado usando reflection…
Negativo. Esse é um bom exemplo de como se pode quebrar o padrão Singleton.
Certa vez, até escrevi um artigo exatamente com esse assunto.
O usuário pode fazer:
//Primeiro, o usuário guarda uma referência ao exemplo numa variável qualquer.
Exemplo exemplo = Exemplo.getInstance();
//Chama killmyself
Exemplo.killMySelf();
//A variável exemplo continua contendo o singleton, portanto, o gc não vai deleta-lo.
Exemplo exemplo2 = Exemplo.getInstance(); //Voilá. Duas instâncias diferentes do seu "singleton".
System.out.println(exemplo == exemplo2); //False. Exemplo e exemplo 2 tem instãncias diferentes do "singleton".
Exemplo.killMySelf(); //Novamente, nulificamos a estática.
Exemplo exemplo3 = Exemplo.getInstance(); //Três cópias...
E assim por diante…
Se você levar reflection em conta, tudo pode ser burlado. Não existem padrões.
Negativo. Esse é um bom exemplo de como se pode quebrar o padrão Singleton.
Certa vez, até escrevi um artigo exatamente com esse assunto.
O usuário pode fazer:
//Primeiro, o usuário guarda uma referência ao exemplo numa variável qualquer.
Exemplo exemplo = Exemplo.getInstance();
//Chama killmyself
Exemplo.killMySelf();
//A variável exemplo continua contendo o singleton, portanto, o gc não vai deleta-lo.
Exemplo exemplo2 = Exemplo.getInstance(); //Voilá. Duas instâncias diferentes do seu "singleton".
System.out.println(exemplo == exemplo2); //False. Exemplo e exemplo 2 tem instãncias diferentes do "singleton".
Exemplo.killMySelf(); //Novamente, nulificamos a estática.
Exemplo exemplo3 = Exemplo.getInstance(); //Três cópias...
E assim por diante…[/quote]
Faz sentido…
[quote=ViniGodoy]
[quote=eclipso]Singleton em Java é um pepino porque pode sempre ser burlado usando reflection...[/quote]
Se você levar reflection em conta, tudo pode ser burlado. Não existem padrões.[/quote]
Tb faz sentido… reflection é uma quebra de padrões terrível… mas as vezes necessário.
Parece que a pergunta foi esquecida…
Mas retomando, pelo que entendi o que voce que é guardar algum objeto scopo “application”, nao seria isso?
[]´s
Humberto
Negativo. Esse é um bom exemplo de como se pode quebrar o padrão Singleton.
Certa vez, até escrevi um artigo exatamente com esse assunto.
O usuário pode fazer:
//Primeiro, o usuário guarda uma referência ao exemplo numa variável qualquer.
Exemplo exemplo = Exemplo.getInstance();
//Chama killmyself
Exemplo.killMySelf();
//A variável exemplo continua contendo o singleton, portanto, o gc não vai deleta-lo.
Exemplo exemplo2 = Exemplo.getInstance(); //Voilá. Duas instâncias diferentes do seu "singleton".
System.out.println(exemplo == exemplo2); //False. Exemplo e exemplo 2 tem instãncias diferentes do "singleton".
Exemplo.killMySelf(); //Novamente, nulificamos a estática.
Exemplo exemplo3 = Exemplo.getInstance(); //Três cópias...
E assim por diante…[/quote]
Blz entao apague o metodo killMySelf, que resolve o problema.
Sim, e não se apaga mais o Singleton…
como eu falei desde o início.
Você só consegue apagar o Singleton usando a classe WeakReference. Assim você consegue garantir que não há referências fortes externamente, como a que eu fiz ali.
Mas ainda assim, com Singleton ou sem Singleton, é praticamente impossível “matar” uma instância.
[quote=Jedi_FeniX]Tem como pegar a instancia de uma classe que já está rodando?
Por que no meu aplicativo eu só posso inicializa uma classe uma única vez e queria saber também se tem como “matar” esta instancia que esta rodando?[/quote]
Você pode usar o padrão descrito no .net, chamado “disposable”. O Java usa isso em algumas classes.
Simplesmente, crie um método “close”, “dispose”, “kill” na sua classe.
Após a invocação desse método, marque alguma propriedade “isDisposed” para true e passe a lançar uma exceção de “ObjectDisposedException”, “UnsupportedOperationException” ou “IllegalStateException” sempre que alguém chamar qualquer método.
Não é exatamente a melhor das políticas… mas é uma alternativa interessante em muitos casos.
Sim, e não se apaga mais o Singleton…
como eu falei desde o início.
Você só consegue apagar o Singleton usando a classe WeakReference. Assim você consegue garantir que não há referências fortes externamente, como a que eu fiz ali.
Mas ainda assim, com Singleton ou sem Singleton, é praticamente impossível “matar” uma instância.[/quote]
Nao se apaga?? e que tal:
exemplo = null;
Você está acompanhando toda discussão, ou só respondendo por impulso a última coisa que lê?
Se retirar o método killMySelf, você terá sempre a referência da variável estática, dentro da classe do Singleton.
Como demonstrado, você não pode simplesmente apagar aquela variável estática, sob o risco de quebrar o padrão Singleton.
Portanto, um objeto singleton não será apagado facilmente. Você até pode manter o killMySelf e usar o padrão disposable que descrevi ali em cima. Isso forçaria que quem capturou uma referência externa tenha que libera-la, já que usa-la dispararia exceção.
De qualquer forma, é menos elegante do que manter a instância do singleton ativa para sempre.
Afinal, uma única instância dificilmente ocupa uma quantidade significativa de memória.
[quote=ViniGodoy]Você está acompanhando toda discussão, ou só respondendo por impulso a última coisa que lê?
Se retirar o método killMySelf, você terá sempre a referência da variável estática, dentro da classe do Singleton.
Como demonstrado, você não pode simplesmente apagar aquela variável estática, sob o risco de quebrar o padrão Singleton.
Portanto, um objeto singleton não será apagado facilmente. Você até pode manter o killMySelf e usar o padrão disposable que descrevi ali em cima. Isso forçaria que quem capturou uma referência externa tenha que libera-la, já que usa-la dispararia exceção.
De qualquer forma, é menos elegante do que manter a instância do singleton ativa para sempre.
Afinal, uma única instância dificilmente ocupa uma quantidade significativa de memória.
[/quote]
Eu estou lendo, agora, voce esta lendo o que estou escrevendo, eu estou escrevendo sobre o que vc escreveu de “Voila” quebrar o singleton e ter 2 variaveis apontando para objetos diferentes.
Leu onde escrevi “exemplo = null”??
Bom ou nao estou te entedendo ou vc é que nao esta me entendendo.
Bom meditemos o seguinte codigo pra ver o que acontece.
Exemplo exemplo = Exemplo.getInstance();
System.out.println(exemplo);
exemplo = null; //matando o singleton, com isso a referencia "instance" da classe Exemplo recebe null, ou seja o mesmo que o antigo metodo killMySelf
System.out.println(exemplo); //imprimi null ou seja onde esta a referencia do singleton que vc fala.
Exemplo exemplo2 = Exemplo.getInstance(); //cria novo singleton
System.out.println(exemplo2);
System.out.println(exemplo == exemplo2); //false, claro exemplo é null
System.out.println(exemplo); // continua imprimindo null, ou seja quantas referencias para o singleton eu tenho???
//1, o que tenho sao 2 "variaveis" porem uma é nula e nao aponta pra lugar algum, entao nao pode ser usada, ao menos que
exemplo = Exemplo.getInstance();
System.out.println(exemplo == exemplo2); //agora true, ou seja apenas um objeto
Claro que pra acabar com o objeto tem que se digitar exemplo = null, porem deixando assim, evitamos ter 2 objetos diferentes da classe Exemplo, ou seja temos sim um singleton.
Ok, mas fazer:
Exemplo exemplo = Exemplo.getInstance();
exemplo = null;
Não mata o singleton. Mata uma referência ao Singleton, mas o objeto Singleton ainda existe, conforme demonstra o resto do seu exemplo.
Ainda existe uma variável estática (que está dentro da classe Exemplo), guardando a referência do Singleton. E o que o autor do tópico perguntou e se há um jeito de eliminar a existência de um objeto, em definitivo. No caso do Singleton, estou tentando demonstrar que não há. Ou melhor até há, mais é muito mais difícil do que com um objeto comum.
Era essa variável que o método killMySelf() tentava apagar exatamente a referência estática, interna e na classe, que mantém o Singleton vivo. E por isso causava a duplicação do Singleton.