dúvida com synchronized

Qual a diferença na execução destes?

void metodo(){
synchronized(this){
//instrução
}
}

synchronized void metodo(){
//instrução
}

void metodo(){
synchronized(this){
//instrução
}
}

O método acima declara um bloco sincronizado (synchronized(this) {//instrução}), onde este método poderá ser chamado por várias Threads, porém, quando uma Thread executar o bloco sincronizado, as demais poderão executar até antes do bloco, e depois terão que esperar a primeira Thread terminar a execução deste bloco, e assim por diante (uma fila, no bloco).

synchronized void metodo(){
//instrução
}

Já o método acima, declara um método sincronizado (synchronized void metodo () {//instrução}), onde somente uma Thread por vez poderá executa-lá (o método por completo).

Espero que ajudado… :slight_smile:

Da forma como o código foi colocado não há diferença entre os dois. Haveria diferença em uma situação como a seguinte:

void metodo1() {
    /* bloco de código 1 */
    synchronized(this){
        /* bloco de código 2 */
    }
    /* bloco de código 3 */
}

synchronized void metodo2() {
    /* bloco de código 1 */
    /* bloco de código 2 */
    /* bloco de código 3 */
}

No método 1 pode haver várias threads executando o blocos de código 1 e 3, mas apenas uma thread por vez executará o bloco 2. No método 2 apenas uma thread por vez poderá executar o método como um todo (blocos 1, 2 e 3 – na seqüência).

Sds,
Jefferson O. Andrade.

A forma

synchronized void m()
{

}

é uma versão simplificada (mas produz o mesmo efeito) que

void m()
{
syncronized (this)
{

}
}

ou seja, só posso usar a versão simplificada se não houver código antes e depois do bloco synchronized como neste caso

void m()
{

syncronized (this)
{

}

}

O segredo para entender sincronização é o argumento passado no bloco synchronized (no caso o this). Na verdade, todo objeto java, seja ela produzido pelo operador new, pelo método newIntance() da class Class, pelo autoponteiro this ou
um próprio objeto Class (obtido pelo método forName() da classe Class) possui um lock único e exclusivo associado a ele. Só quem possui o lock especificado como argumento de um bloco sincronizado pode executar o código do seu corpo. O lock é obtido passando-se uma referência ao objeto pretendido.

Completando. Os métodos sincronizados têm a seguinte equivalência:

static synchronized void s()
{

}

equivale a

static void s()
{
synchronized(Class.forName(“nome_da_classe”))
{

}
}