Importância de documentar a thread safety
- Parte do contrato da classe: A forma como uma classe lida com acesso concorrente é crucial para seus clientes.
Riscos de suposições erradas:
- Sincronização deficiente ou excessiva (Itens 78 e 79).
- Erros graves no comportamento do programa.
Problemas com o uso de synchronized como indicador
- Detalhe de implementação: Não é parte da API pública.
- Visão simplista: Thread safety não é uma propriedade binária (tudo ou nada); há níveis diferentes.
Níveis de thread safety
Imutável:
- Comportam-se como constantes.
- Não necessitam de sincronização externa.
- Exemplos: String, Long, BigInteger.
Incondicionalmente thread-safe:
- Instâncias mutáveis, mas com sincronização interna suficiente.
- Uso concorrente seguro sem sincronização adicional.
- Exemplos: AtomicLong, ConcurrentHashMap.
Condicionalmente thread-safe:
- Similar ao incondicional, mas alguns métodos requerem sincronização externa.
- Exemplo: Coleções de Collections.synchronized, que exigem sincronização ao iterar:
Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<>());synchronized (syncMap) { for (String key : syncMap.keySet()) { // Iteração segura }}
Sem thread safety:
- Necessário envolver métodos com sincronização externa.
- Exemplos: ArrayList, HashMap.
Hostil à thread:
- Não são seguras mesmo com sincronização externa.
- Geralmente resultado de erros, como modificação de dados estáticos sem sincronização.
Como documentar a thread safety
Documentação clara no Javadoc:
- Nível de segurança oferecido.
- Métodos ou sequências que requerem sincronização externa.
- Bloqueios específicos a serem usados.
Exemplo de documentação de sincronização para iteração:
/** * É necessário sincronizar manualmente ao iterar sobre as views deste mapa. * Exemplo: * synchronized (map) { * for (Object key : map.keySet()) { * // Iteração segura * } * } */
Uso de objeto de bloqueio privado
Vantagens:
- Evita interferência de clientes e subclasses.
- Permite controle de concorrência mais sofisticado no futuro.
Exemplo:
private final Object lock = new Object();public void threadSafeMethod() { synchronized (lock) { // Código protegido }}
Campos final: Protegem contra alterações acidentais no objeto de bloqueio.
Cuidados ao projetar classes para herança
- Usar o mesmo bloqueio em subclasse e classe base pode causar interferências.
- Preferir o bloqueio privado para evitar conflitos.
Resumo final
- Documente sempre a thread safety de uma classe (com texto ou anotações).
- Não confie apenas no modificador synchronized para documentar.
- Para classes incondicionalmente thread-safe, considere usar objetos de bloqueio privados.
- Classes condicionalmente thread-safe devem especificar quais bloqueios usar e quando.
Top comments(0)
Subscribe
For further actions, you may consider blocking this person and/orreporting abuse