Questão nº 66
Questão de Boas Práticas e Padrões em TIC · FCC PMSP Analista TIC 2025 (nº 66)
Uma prefeitura está desenvolvendo um sistema integrado de gestão pública que centraliza diversas funções administrativas. Para garantir a consistência dos logs de sistema, foi decidido implementar o padrão Singleton para a classe de gerenciamento de logs. Um dos desenvolvedores sugeriu a seguinte implementação em Java:
public class LogManager {
private static LogManager instance;
private LogManager() {}
public static LogManager getInstance() {
if (instance == null) {
instance = new LogManager();
}
return instance;
}
}
Em condições ideais, para garantir que apenas um thread possa executar o método getInstance por vez, evitando a criação de múltiplas instâncias em um ambiente multithread, e considerando que o desempenho não é a principal prioridade, é adequado
- Aadicionar o modificador synchronized ao método `getInstance` para torná-lo thread-safe. (alternativa correta)
- Bdeclarar o atributo `instance` como flexible para garantir a consistência em ambientes multithread.
- Cimplementar a inicialização precoce (lazy initialization), instanciando `instance` imediatamente após a declaração.
- Dredefinir o construtor como público, garantindo assim que apenas uma instância seja criada a partir de chamadas externas.
- Eadicionar um bloco try-catch ao método `getInstance` para lidar com a exceção `MultithreadException`.
Resposta comentada
Gabarito Alternativa A
O padrão Singleton garante que uma classe tenha apenas uma única instância em todo o sistema e fornece um ponto de acesso global a ela, sendo útil para recursos compartilhados como gerenciadores de logs ou configurações.
(A) Correta: Adicionar o modificador synchronized ao método getInstance() faz com que apenas um thread por vez possa executar esse método. Isso resolve a condição de corrida (race condition) onde múltiplos threads poderiam, simultaneamente, verificar que instance é null e tentar criar novas instâncias, garantindo que a inicialização (instance = new LogManager();) ocorra apenas uma vez.
(B) Incorreta: Não existe o modificador flexible em Java. O modificador volatile existe e garante visibilidade de mudanças entre threads, mas sozinho não impede a criação de múltiplas instâncias em uma condição de corrida no bloco if (instance == null).
(C) Incorreta: A implementação fornecida já utiliza inicialização preguiçosa (lazy initialization), onde a instância é criada apenas quando solicitada. A "inicialização precoce" (eager initialization) é uma estratégia diferente (instanciar instance na declaração da variável estática) que é inerentemente thread-safe, mas a alternativa propõe "implementar" algo que já está sendo feito (lazy) ou sugere uma mudança de estratégia que não é uma correção direta para a thread-safety do método getInstance existente.
(D) Incorreta: Redefinir o construtor como public permitiria que qualquer parte do código criasse novas instâncias de LogManager usando new LogManager(), quebrando completamente o propósito do padrão Singleton de ter apenas uma instância. A armadilha aqui é a frase "garantindo assim que apenas uma instância seja criada a partir de chamadas externas", que é o oposto do que um construtor público faria.
(E) Incorreta: Java não possui uma MultithreadException padrão que seria lançada automaticamente em caso de condição de corrida. O uso de blocos try-catch é para tratamento de exceções, não para garantir a thread-safety na criação de objetos.
Fonte: FCC PMSP Analista TIC 2025 Analista de Planejamento e Desenvolvimento Organizacional - Tecnologia da Informação e Comunicação (Caderno Tipo 001). Reproduzida para fins de estudo.