Se você tiver alguns métodos que não estão sincronizados e estão acessando e alterando as variáveis da instância. No seu exemplo:
private int a;
private int b;
qualquer número de threads pode acessar esses métodos não sincronizados ao mesmo tempo em que outro thread estiver no método sincronizado do mesmo objeto e pode fazer alterações nas variáveis da instância. Por exemplo: -
public void changeState() {
a++;
b++;
}
Você precisa evitar o cenário em que métodos não sincronizados estão acessando as variáveis da instância e alterando-os, caso contrário não há sentido em usar métodos sincronizados.
No cenário abaixo: -
class X {
private int a;
private int b;
public synchronized void addA(){
a++;
}
public synchronized void addB(){
b++;
}
public void changeState() {
a++;
b++;
}
}
Somente um dos encadeamentos pode estar no método addA ou addB, mas ao mesmo tempo qualquer número de encadeamentos pode inserir o método changeState. Dois threads não podem inserir addA e addB ao mesmo tempo (devido ao bloqueio no nível do objeto), mas ao mesmo tempo qualquer número de threads pode inserir changeState.
synchronized (this)bloco ao redor do corpo do método. O objeto "this" não fica bloqueado, mas o objeto "this" é usado como o mutex e o corpo é impedido de executar simultaneamente com outras seções de código também sincronizadas em "this". Não tem efeito em outros campos / métodos "this" que não são sincronizados.