Pergunta

Eu tenho um objeto estático definido na minha classe de log, ao longo das linhas de:

   class myLoggingClass {
     static java.util.Properties properties;
     ...
     ...
   }

De acordo com o meu livro de referência, isto significa que o objeto propriedades é compartilhado por todas as instâncias da minha classe.

Eu acho essa definição insuficiente. Eu estou escrevendo uma classe que está sendo chamado mais de uma vez em cada aplicação em nosso projeto.

Além disso, nosso projeto utiliza vários serviços web que funcionam no mesmo recipiente tomcat. Cada serviço web pode ter vários segmentos.

A Máquina Virtual Java em execução no host também pode executar uma ou mais aplicações do cliente de serviços web, que funcionam externo para tomcat.

Assim, por esta definição, eu posso ter tomcat executando vários serviços web com fios, cada um com vários objetos, que podem conter uma instância da minha classe.

Também pode haver um ou dois clientes web que funcionam fora do tomcat, mas dentro da mesma JVM. Será que todas desses casos de minha classe compartilham o mesmo objeto propriedades? Isso tornaria JVM-wide.

Se o objeto estático é não JVM-wide, alguém sabe em que nível cada um existiria? Um por contentor tomcat? Um por serviço web, e um por aplicativo cliente de serviço da Web independente?

O motivo: Quando eu atualizar minhas propriedades, estou ficando um java.lang.ConcurrentUpdateException de java.util.Properties.

Eu estou usando uma variável booleana estática para "bloquear" as propriedades do objeto quando as minhas atualizações de classe, mas isso é não manter a exceção ocorra.

Isto leva-me a acreditar que o objeto estático usado na minha classe não pode ser no mesmo nível de escopo que o utilizado em java.util.Properties ... Mas isso é apenas um palpite.

Obrigado por qualquer ajuda.

Foi útil?

Solução

A causa provável de sua ConcurrentModificationException é que você está interagindo através dos valores / entradas do objeto Properties em um segmento enquanto outro modifica-lo ao mesmo tempo. Você não pode fazer isso.

Você pode elaborar sobre o mecanismo de bloqueio que você mencionou aqui:

Eu estou usando uma variável booleana estática para "bloquear" o objeto de propriedades quando meus atualizações de classe, mas isso não é mantendo a exceção ocorra.

?

Porque não soa como se você estiver usando o built-in o bloqueio e sincronização métodos em Java.

Algo como isso deve evitar tópicos da leitura do objeto Properties enquanto outra thread atualiza-lo:

static Object lockObject = new Object();

...

synchronized(lockObject) {
     // access the Properties object
}

Note que você vai precisar fazer isso todas vez que você acessar o objeto Properties, quer para lê-lo ou modificá-lo.

Além disso Eu nunca recomendaria objetos estáticos para compartilhar dados entre todas as instâncias ou lockObjects estáticos - dados global é mal -. Mas soa como se você precisa isto por alguma razão

Outras dicas

Estática não são "compartilhados por todas as instâncias de uma classe" - eles são não relacionados para casos; eles pertencem ao digite si . Em particular, variáveis ??estáticas são perfeitamente utilizável sem qualquer casos sendo criado.

Isso dá uma pista sobre o alcance da estática: eles estão no escopo pelo objeto Class representando a classe que contém, que é por sua vez escopo pela ClassLoader que carregá-la

.

Dependendo de onde a biblioteca é colocado, a variável estática pode estar em toda a JVM ou web-ampla aplicação -. Ou possivelmente algo entre os dois, se Tomcat suporta múltiplos de hospedagem (não me lembro de improviso)

Observe a documentação do Tomcat para saber como as bibliotecas são definidos e como se relacionam com carregadores de classe. Por exemplo, aqui está a Tomcat 6.0 ClassLoader como a guia e o equivalente para 5,5 .

Como funciona o booleano "bloqueio"? Você realmente deve usar um bloqueio adequado (synchronized) para se certificar de que cada uso do objeto propriedades (tanto ler e escrever, incluindo bloqueio durante todo o período durante o qual você iterate através dele) está devidamente bloqueado.

Em vez de mudar o objeto Properties "ao vivo", você já considerou tratar isso como imutável - por isso, quando você deseja atualizar as propriedades, você toma uma cópia, mudança que, em seguida, fazer a copiar a versão "ao vivo"? Você ainda precisará evitar que dois tópicos diferentes de fazer alterações ao mesmo tempo (ou você pode perder alguns), mas é provável que faça lado a leitura muito mais fácil e mais eficiente.

Você pode achar que o âmbito dessa variável um static é limitado a um por ClassLoader que carregou sua classe. Eu não tenho certeza de como Tomcat organiza seus ClassLoaders, por isso é difícil dizer o que a extensão do escopo será nesse ambiente.

Poderia ser um problema de carregador de classe, onde o frasco que contém a sua classe é duplicado em cada WEB-INF / lib de suas diferentes aplicações? Se assim for, gostaria de tentar adicionar este frasco para libs Tomcat e não para o aplicativo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top