Eu tenho dois métodos em minha classe, que será executado dentro do ambiente concorrente:
class Clazz {
private int counter = 0;
private volatile Map<..> map = new ConcurrentHashMap<>();
private int[] array;
public void concurrentMethod() {
...perform some actions with map...
}
public int nonConcurrentMethod() {
...reinitialize the map...change references...
counter++;
return array[counter];
}
}
A questão é o seguinte: assumindo que nonConcurrentMethod
está a ser chamado por apenas um thread por vez, devo especificar explicitamente counter
e array
como um volatile
campo? Faça balcão atomic
?
Meus pensamentos são que seria melhor para garantir que tudo deve funcionar sem falhas em uma produção real.
Geralmente é toda a classe que tem a semântica específicos thread-safe por exemplo, HashMap
não é thread-safe, enquanto ConcurrentHashMap
é. Isto é especialmente importante se você está construindo uma biblioteca, as pessoas podem ir ao redor seu projeto chamando nonConcurrentMethod()
de vários segmentos.
IMO, se você não pode dividir Clazz
-se em duas classes distintas com diferentes semântica thread-safe seria prudente fazer nonConcurrentMethod()
thread-safe. No caso nonConcurrentMetho()
é chamado de vários segmentos do desempenho irá degradar, mas a correção será mantido, espero evitando difícil encontrar bugs.
Pode tentar um bloqueio interno, que esperamos que não será demasiado caro devido ao bloqueio inclinado optimizá-la quando o bloqueio é obtido a partir de um único segmento:
private final Object lock = new Object();
public int nonConcurrentMethod() {
synchronized(lock) {
...reinitialize the map...change references...
counter++;
return array[counter];
}
}
Certifique-se de que pelo menos um dos Clazz
campos é final
para garantir a publicação segura .