Duvida sobre synchronized

espero que vcs entendam meu raciocionio :stuck_out_tongue:

supondo que eu tenho um metodo synchronized que incrementa um campo de um objeto qlq. E supondo que disparo uma thread com um outro metodo que nao é synchronized que tenta atualizar essa mesma variavel.

tipo, essa thread nao synchronized vai conseguir modificar valor da variavel, correto ?

pergunto isso pq sempre achei que um metodo synchronized nunca fosse escalonado (tipo, executava do inicio ao fim, sem dar chance a outras threads … ou seja, liberando apenas qdo terminasse). Mas pelo o que tenho visto em minhas execucoes, isso nao é verdade. pelo que tenho visto, um metodo nao syncronized pode modificar variaveis que estao sendo usadas por um metodo syncronized.

estou correta ?

Sim. Para isto o ideal é vc colocar variáveis críticas para serem acessadas ou alteradas dentro de métodos sincronizados.

Se alguma thread tem o lock do método (está dentro dele) nenhuma outra thread vai poder entrar na execução.

Vc tem que pensar no método acessado e não no que acessa. Se o método acessado é synchronized, só uma thread pode entrar nele por vês.

A execução não é atômica como vc pressupos, mas a thread q tem o lock do método vai executar ele inteiro, de uma vez, ou em várias etapas. Mesmo que alguma outra thread tenta entrar no método ela não consegue.

É como se a thread q entra primeiro trancasse o método por dentro e só o abrisse quando termina a execução.

Falow!

Só pra clarificar: o acesso a um método synchronized por uma thread obtém o lock do objeto, e não do método. Isso significa que nenhum método synchronized daquele objeto estará sendo executado de forma concorrente por outra thread.

http://java.sun.com/docs/books/tutorial/essential/concurrency/syncmeth.html

eu tenho tres perguntas :smiley:
1- eu tenho um metodo que eh acessado por 4 threads diferentes, com variaveis locais e outras statics , acontece q de vez em qdo ele gera um erro de NullPoiterException, esse metodo trata da manipulaçãode socket, eh possivel q as threads estejam tentando alterar as variaveis staticas ao mesmo tempo ou algo parecido, e esse metodo deve ou nao ser declarado como syncronizad?

2 - eu tenho uma thread q controla um ArrayList onde instancio varias classes, os metodos de manipulação da ArrayList sao acessados por vairas outras Threads, eu devo tb declara-los com shyncronized?

3- para a thread 1 acessar a 2 , eu passei como parametro no construtor a thread 2, e para a thread 2 acessar a 1 eu criei um metodo dentro da 2 q eh chamado pela 1 e faz um atributo local receber uma referencia a thread 1, isso está certo? ou foi gambiarra da feia :frowning:

Por que você não usa um Vector? Ele é sincronizado por padrão.

Sim.

E o pior, corre-se o risco de uma thread fazer a modificação e a outra não a ver.

Cada thread está autorizada a criar um cache local das variáveis que está acessando. Nesse caso, é possível que uma thread modifique uma variável ou atributo, enquanto ao mesmo tempo outra leia um valor desatualizado.

Isso não ocorre caso o acesso esteja sendo feito num método sincronizado ou caso a variável seja volátil.

O que é importante é manter a sincronização, sobre o mesmo objeto de sincronização, enquanto está se fazendo o acesso multi-thread. É uma “rule of tumb”: Se vai acessar variáveis em paralelo, use sinchronized.

agora eu entendi :D, por isso q de vez em qdo gerava uma exception de NullPointer error e outras vezes ArrayIndexOutOfBounds , entao era por isso :smiley:

eu botando todos os metodos syncronized resolve neh?

[quote=Wolf_X]agora eu entendi :D, por isso q de vez em qdo gerava uma exception de NullPointer error e outras vezes ArrayIndexOutOfBounds , entao era por isso :smiley:

eu botando todos os metodos syncronized resolve neh?[/quote]

Sim… ou declarando a variável como volatile. Geralmente o volatile é mais útil em variáveis que são simples flags.