Bom, programo em java já a algum tempo, mas nunca parei pra pensar neste problema em particular
tenho uma classe A onde existe uma variavel
a classe A é instanciada e utilizada em B
porém necessito fazer consulta à tal variavel na classe C
mas aí que está. não posso fazer a var static e instanciar a classe de novo, pq ela é runnable, thread, e nao pára, só pode haver uma execução da mesma
uma soluçao que pensei é manter esta tal variavel fora destas classes e transforma-la em uma variavel acessivel a todas as classes
Mas o melhor jeito de fazer é implementar um Singleton.
M
mdill
entendo, pesquisei por este padrão singleton que vc disse, porem nao entendo como devo proceder, como instancio a classe pela primeira vez
se ele diz que o metodo eh privado…
pablosaraiva
O construtor é privado, mas você vai ter um método público que vai sempre retornar a mesma instância do Singleton pra você.
Repare no seguinte. A classe possui uma instância do Singleton. Como o construtor é privado, a classe conseguiu instanciar, mas você não consegue fazer isso de fora.
O método público getInstance() vai te retornar sempre a mesma instância do seu Singleton.
M
mdill
poxa que maravilha
haha
muito obrigado ai eh isso mesmo que eu queria… heheheh valeu!
porem, isso nao é uma especie de gambiarra?
pablosaraiva
É um padrão de projeto bem conhecido.
Se torna gambiarra se for feito mal uso dele, mas existem casos em que ele é bem aplicado.
Repare que editei o post acima e tornei o método getInstance() static.
M
mdill
ah bom, então ta show, pois é eu achei um exemplo tb que usa um tal de “synchronized” aí deixei tbm…
acho que neste caso essa solução eh a melhor mesmo, pois tem mesmas as caracteristicas
valeuu aí cara
pablosaraiva
synchronized você vai usar apenas se a sua aplicação foi multi-thread.
Você marca os recursos compartilhados como synchronized e o java não permite que duas threads acessem simultaneamente o conteúdo.
maior_abandonado
o mais indicado é deixar o metodo sincronizado mesmo… é uma garantia a mais que só terá uma unica instancia (objetivo do singleton…)
ViniGodoy
pablosaraiva:
Variável global nunca é elegante.
Mas o melhor jeito de fazer é implementar um Singleton.
Na verdade, essa foi uma péssima sugestão. Você efetivamente está dizendo para ele criar um Singleton para ser usado como variável global, e esse não é propósito do Singleton. É um exemplo de uso errado do padrão.
Seu runnable continuará com os valores definidos, mesmo que a thread tenha terminado sua execução. Se você explicar melhor o que cada classe faz, talvez seja possível chegar a uma solução melhor. Mas algumas alternativas podem ser:
Usar um trecho sincronizado na classe C. Isso é interessante se a thread ainda estiver rodando sobre o Runnable. Trechos sincronizados reduzem o paralelismo, mas podem ser adequados em diversas situações;
Usar o próprio Runnable, desde que a thread já tenha terminado. Você pode fazer isso criando um método get() do valor em C, com uma instrução join() logo no início. Assim, quem chamar o método será obrigado a esperar a thread terminar, antes de obter o valor em C. Outra alternativa é transformar C num Future;
Fazer C copiar o valor para um objeto qualquer, e fazer com que B leia desse objeto. Cópias de dados são boas alternativas usando threads pois elas maximizam o paralelismo.
Tudo vai depender de como seu programa esteja organizado.
pablosaraiva
ViniGodoy:
pablosaraiva:
Variável global nunca é elegante.
Mas o melhor jeito de fazer é implementar um Singleton.
Na verdade, essa foi uma péssima sugestão. Você efetivamente está dizendo para ele criar um Singleton para ser usado como variável global, e esse não é propósito do Singleton. É um exemplo de uso errado do padrão.
Eu comecei dizendo que usar variável global nunca é elegante. Na sequencia, mostrei como fazer.
Concordo que conhecendo o problema dele, pode-se sugerir soluções mais apropriadas.
ViniGodoy
pablosaraiva:
Eu comecei dizendo que usar variável global nunca é elegante. Na sequencia, mostrei como fazer.
Concordo que conhecendo o problema dele, pode-se sugerir soluções mais apropriadas.
Mas o melhor jeito de fazer é implementar um Singleton.
Na verdade, essa foi uma péssima sugestão. Você efetivamente está dizendo para ele criar um Singleton para ser usado como variável global, e esse não é propósito do Singleton. É um exemplo de uso errado do padrão.
Eu comecei dizendo que usar variável global nunca é elegante. Na sequencia, mostrei como fazer.
Concordo que conhecendo o problema dele, pode-se sugerir soluções mais apropriadas.
pablosaraiva:
Variável global nunca é elegante.
Mas o melhor jeito de fazer é implementar um Singleton.
Decida-se.
pablosaraiva
marcio_gs,
Eu estava decidido.
Disse que não é elegante ter variáveis globais e que caso o cara realmente queira fazer isso, que um Singleton seria uma boa escolha.
Obviamente o Vini e outros discordam.
Acredito então que quem estiver interessado no assunto deve realmente ler o link que o Vini postou para outros posts.
In Vini we Trust.
ViniGodoy
Na verdade, existem soluções melhores para o problema, e era elas que eu queria discutir. Por isso o colega deve postar algum código, e dar mais exemplos do que quer fazer. Se formos falar de singleton, teremos outro post longo, como os dos links que postei.
M
marcio_gs
pablosaraiva:
marcio_gs,
Eu estava decidido.
Disse que não é elegante ter variáveis globais e que caso o cara realmente queira fazer isso, que um Singleton seria uma boa escolha.
Obviamente o Vini e outros discordam.
Acredito então que quem estiver interessado no assunto deve realmente ler o link que o Vini postou para outros posts.
Entendi diferente. Meu erro então =)
In Vini we Trust. :)
É, realmente a educação e inteligência do ViniGodoy fazem suas respostas terem bastante crédito.
lina
pablosaraiva:
Variável global nunca é elegante.
Oi,
Uma dúvida: Pq utilizar uma variavel global nunca é elegante?
Tchauzin!
ViniGodoy
Com o tempo, você começa a perder o controle de que locais ela é alterada. E isso torna o sistema muito complicado de se manter.
É diferente no entanto de se ter constantes globais. Constantes são plenamente válidas.
ViniGodoy
marcio_gs:
pablosaraiva:
In Vini we Trust. :)
É, realmente a educação e inteligência do ViniGodoy fazem suas respostas terem bastante crédito.
Opa, valeu pessoal. A gente faz o que pode…
(podem ver que eu não dou pitaco no fórum de web)
lina
Com o tempo, você começa a perder o controle de que locais ela é alterada. E isso torna o sistema muito complicado de se manter.
É diferente no entanto de se ter constantes globais. Constantes são plenamente válidas.
Oi,
Claro, você poderá perder o controle sobre ela, porém a palavra utilizada: nunca foi um tanto que inadequada.
Se você tem uma classe “pequena” não tem pq não utiliza-la.
Constantes globais (final) é uma coisa totalmente diferente, até porque não é permitido a alteração do seu valor.
Tchauzin!
M
mdill
olá caros colegas, vejam bem
há uma classe main que estancia todas as outras classes que são telas ou procedimentos do meu programa
então existe uma classe responsavel de enviar dados coletados para uma das telas que trata dados, então enquanto o programa roda, esta classe está funcionando
a classe main instancia essa classe que vai coletar dados, e essa classe que coleta dados instancia esta classe que trata dados
a classe que trata os dados grava em banco de dados e também manda eles para uma classe instanciada de medidores. onde serão exibidos…
porém essa classe de medidores foi instanciada em Main, e a classe que trata dados mexe nela fazendo isto: Main.telaMedidores.funcao() pois ela é static
poderia eu utilizar então a variavel da classe que coleta dados static e mexer nela desta forma na tela de medidores, onde tenho que alterá-la?
abraços
luistiagos
aproveitando o embalo…
sobre problemas de sincronismo com Singletons
se fizermos isto:
pois se for pensar bem… posso estar enganado mais no primeiro codigo usa uma constante ou seja a primeira thread que carregar o objeto vai instanciar e o resto vai pegar a mesma instancia…
á diferença em termos de sincronismo entre estes 2 codigos?
luistiagos
mais alguem?
ViniGodoy
O primeiro código é tão seguro quanto o segundo. Com a diferença de ser mais simples.
gomesrod
Com o tempo, você começa a perder o controle de que locais ela é alterada. E isso torna o sistema muito complicado de se manter.
Para que não pareça uma “baboseira teórica”, um daqueles “Faça assim porque SE UM DIA…”, vou dar meu testemunho!
[i]Em uma empresa onde eu trabalhava há alguns anos, havia um aplicativo em VB que cuidava da criptografia e formatação de mensagens. Essas mensagens eram transmissões de transações financeiras do cliente para outras instituições.
Quem aqui conhece o velho VB (versões anteriores ao .NET) sabe que ele é bastante permissivo e até mesmo incentiva as mais grotescas gambiarras. Uma delas é a declaração e uso de variáveis globais, é facinho facinho. É o jeito utilizado por uma boa parcela dos desenvolvedores para passar informação entre funções ou entre módulos.
Pois bem… um certo diz começou a acontecer um erro na formatação dessas mensagens. O erro era daquele tipo que acontece esporadicamente em Produção e JAMAIS em desenvolvimento. Resultado: Essa situação continuou por meses sem que se descobrisse a causa. E agora é que vem a pior parte, dependendo da transação e do horário em que ocorria o erro, o cliente precisava pagar uma multa que era repassada para a software house (nós), o valor era de R$6.000,00 em cada ocorrência. O prejuízo ao longo desses meses foi enorme!
Depois de muito muito muito (MAS MUITO MESMO! AO QUADRADO) trabalho, descobriu-se a causa: em certas situações era necessário dar um tratamento diferenciado para determinadas mensagens, e como isso era feito? ATIVANDO UMA FLAG GLOBAL antes de tratar essas mensagens específicas. E nas próximas transações, adivinha o que acontecia… esta flag estava ativada e zuava toda a formatação.
Claro que depois de se saber isso o problema foi resolvido rapidamente…[/i]
Moral da história: #1: Mesmo que sua linguagem permita ou você descubra aqueeele esqueminha fácil, NAO USE VARIAVEIS GLOBAIS! NUNCA! Lembre-se que sempre existem outras alternativas. #2: Eu não tive culpa nesse caso, na época eu não era desenvolvedor e sim um simples analista de suporte
ViniGodoy
Onde eu trabalhava um grupo menos experiente criou uma variável global e importantíssima chamada i. Ocorria direto shadowing com essa variável. E, em alguns módulos, alguns programadores usavam o i no for, achando que a variável global servisse só com um syntax suggar para não ter que ficar redeclarando i…
Ou seja, instabilidade em todo lugar.
pedroroxd
ViniGodoy:
Onde eu trabalhava um grupo menos experiente criou uma variável global e importantíssima chamada i. Ocorria direto shadowing com essa variável. E, em alguns módulos, alguns programadores usavam o i no for, achando que a variável global servisse só com um syntax suggar para não ter que ficar redeclarando i…
Ou seja, instabilidade em todo lugar.
Poco burro O_o
Chamar 1 variável de global de i, bem fácil de diferenciar
¬¬’
lina
Com o tempo, você começa a perder o controle de que locais ela é alterada. E isso torna o sistema muito complicado de se manter.
Para que não pareça uma “baboseira teórica”, um daqueles “Faça assim porque SE UM DIA…”, vou dar meu testemunho!
[i]Em uma empresa onde eu trabalhava há alguns anos, havia um aplicativo em VB que cuidava da criptografia e formatação de mensagens. Essas mensagens eram transmissões de transações financeiras do cliente para outras instituições.
Quem aqui conhece o velho VB (versões anteriores ao .NET) sabe que ele é bastante permissivo e até mesmo incentiva as mais grotescas gambiarras. Uma delas é a declaração e uso de variáveis globais, é facinho facinho. É o jeito utilizado por uma boa parcela dos desenvolvedores para passar informação entre funções ou entre módulos.
Pois bem… um certo diz começou a acontecer um erro na formatação dessas mensagens. O erro era daquele tipo que acontece esporadicamente em Produção e JAMAIS em desenvolvimento. Resultado: Essa situação continuou por meses sem que se descobrisse a causa. E agora é que vem a pior parte, dependendo da transação e do horário em que ocorria o erro, o cliente precisava pagar uma multa que era repassada para a software house (nós), o valor era de R$6.000,00 em cada ocorrência. O prejuízo ao longo desses meses foi enorme!
Depois de muito muito muito (MAS MUITO MESMO! AO QUADRADO) trabalho, descobriu-se a causa: em certas situações era necessário dar um tratamento diferenciado para determinadas mensagens, e como isso era feito? ATIVANDO UMA FLAG GLOBAL antes de tratar essas mensagens específicas. E nas próximas transações, adivinha o que acontecia… esta flag estava ativada e zuava toda a formatação.
Claro que depois de se saber isso o problema foi resolvido rapidamente…[/i]
Moral da história: #1: Mesmo que sua linguagem permita ou você descubra aqueeele esqueminha fácil, NAO USE VARIAVEIS GLOBAIS! NUNCA! Lembre-se que sempre existem outras alternativas. #2: Eu não tive culpa nesse caso, na época eu não era desenvolvedor e sim um simples analista de suporte :D
Onde eu trabalhava um grupo menos experiente criou uma variável global e importantíssima chamada i. Ocorria direto shadowing com essa variável. E, em alguns módulos, alguns programadores usavam o i no for, achando que a variável global servisse só com um syntax suggar para não ter que ficar redeclarando i…
Oi,
Tudo na programação envolve estudo.
Dica: Antes de sair programando é necessário ter: Modulação, Estruturas, Desenhos (UML) etc…
Provavelmente o que aconteceu na sua empresa foi realmente um CDPG*. Onde o programador não sabia o que estava fazendo, ou seja, não fez a analise da programação antes de faze-la.
Como eu disse: utilizar uma variavel global em programas/sistemas grandes é muito complicado. Principalmente em sistemas que fazem uso de processamento paralelo ou threads…
O fato disso é essa tal flag!
Você define um valorzinho nela globalmente (Pensando assim: AAAA! quando ela chegar aqui o status dela vai ser esse…) porém como existem outros processos, ela irá chegar com o status diferente do esperado.
E como fazer para encontrar esse problema?! Debugando!!! não!!! pois em debug não acontece…
Pronto. CDPG* completa.
Antes de usar uma variavel global (em sistema grande), deve-se pensar: O que eu posso fazer para evitar essa variavel?? R: Estudar…
*CDPG: Cagada de programador…GRANDE!
Obs: Não preciso nem comentar em relação: Definir variáveis com ‘a’, ‘b’ e ‘i’
Tchauzin!
M
marcobiscaro2112
Genial! Tão genial que chega a ser engraçado… :lol: