Acontece que não estou conseguindo sincronizar, pois, o incremento da variável nunca dá 10.000. Alguém pode me dizer o que está acontecendo e como consigo fazer essa sincronia?
hahaha, você caiu na mesma pegadinha que eu já cai uma vez. Nunca use um objeto Integer , Double, etc. para sinronizar threads. Isso acontece porque quem atua como monitor é o objeto, e não a variável. Quando você entra no bloco sincronizado e incrementa a variável loss o objeto usado como monitor é descartado, e a variável de referência loss passa a apontar para um novo objeto. Uma maneira de resolver isso seria usar um objeto exclusivamente com a função de servir como monitor, de preferência que seja final:
final Object lossMonitor = new Object();
Integer loss = 0;
void incrementSync(){
synchronized(lossMonitor){
loss++;
}
}
Muito obrigado rmendes08, eu segui suas dias acima e consegui melhorar muito o sincronismo. Porém, percebo que ele não está totalmente estável. Na maioria das vezes que eu rodo eu consigo obter 10000, mas algumas vezes eu obtenho 9848, 9745, etc. Estou mandando o meu código novamente.
final Teste t = new Teste();
public void TesteThread(){
t.setCount(0);
ExecutorService executor = Executors.newFixedThreadPool(2);
IntStream.range(0, 1000).
forEach(i -> executor.submit(this::incrementSync));
executor.shutdown();
System.out.println(t.getCount()); // 8489
}
void incrementSync(){
synchronized(t){
t.setCount(t.getCount()+1);
}
}
Minha classe teste inteira
public class Teste {
private int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
o shutdown() diz apenas que a partir desse momento o executor não vai mais aceitar submissões, isso não implica que a thread atual vai bloquear até que todas as outras terminem. Para fazer essa sincronização você precisa do método awaitTermination():