Sincronização

Referente a sincronização de variáveis, um bloco synchronized pode conter uma instrução de return, ou seja, após a execução do return é garantida a escrita na memória principal das variáveis utilizadas dentro do bloco ?

Ex:

private int i = 0;
private int teste() {
synchronized(mutex) {
i++;
return i;
}
}

ou o correto é fazer desta forma:

private int i = 0;
private int teste() {
int x;
synchronized(mutex) {
i++;
x = i;
}
return x;
}

Fiquei na dúvida se o return se enquadra no mesmo caso de disparar exceptions (método stop) dentro do bloco sincronizado, ou seja, você até fazer uso dele mas desde que entenda os riscos envolvidos em tal operação.

É melhor fazer da primeira forma.

Sempre que o código sai do bloco sinchronized, seja por uma exception, return ou pelo fluxo normal, a sincronização termina.

Outra coisa, ao postar código, use a tag code:
http://www.guj.com.br/posts/list/50115.java

.

[quote=ViniGodoy]É melhor fazer da primeira forma.

Sempre que o código sai do bloco sinchronized, seja por uma exception, return ou pelo fluxo normal, a sincronização termina.

Outra coisa, ao postar código, use a tag code:
http://www.guj.com.br/posts/list/50115.java[/quote]

Opa, valeu pela dica, usarei a tag code na próxima vez.

Não se se entendi bem a resposta, então vou abusar um pouco da sua paciência e acrescentar mais informações sobre o meu questionamento para aprofundarmos mais a questão:

Procurando aprender mais sobre esse obscuro assunto que é Threads, me deparei com o artigo “Why is Thread.stop deprecated?”. Nele entendi que o método stop não é recomendado pois ele força a liberação dos locks dos objetos de maneira anormal, ou seja, deixando as variáveis do bloco sincronizado com valores incosistente. No meu entendimento inconsistente seria a não garantia da sincronização dos valores trabalhados no stack com os contidos no heap, em outras palavras a não execução da instrução de fechamento do bloco sincronizado.

citando o artigo: “The monitors are unlocked as the ThreadDeath exception propagates up the stack”, ThreadDeath é a exception disparada ao se invocar o método stop.

Com base neste meu entendimento, que talvez esteja equivocado, fiquei imaginando se o return teria a possibilidade de também liberar os locks dos objetos de maneira anormal.

Não, não tem. O stop() era uma outra thread A forçar a interrupção de uma thread B. A thread B era morta através de chamadas ao SO. E nada garantia que códigos que fechavam arquivos, resultsets ou outros recursos, seriam executados.

Note que o ThreadDeath nem sequer é uma exception, e sim um Error:
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/ThreadDeath.html

Como o return ou exceptions são atos que ocorrem na própria thread que vai morrer, não há problema. É um encerramento normal do bloco. A VM se encarrega de encerrar os locks presos. Mas você ainda tem que cuidar para fechar conexões, sockets, etc, colocando seus closes() devidamente num bloco finally, e tratando corretamente as exceptions.