O Que é Synchronized?

Gente, estou estudando esse código :

[code]package WormGame;

// Obstacles.java
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th

/* A collection of boxes which the worm cannot move over
*/

import java.awt.*;
import java.util.ArrayList;

public class Obstacles
{
private static final int BOX_LENGTH = 12;

private ArrayList boxes; // arraylist of Rectangle objects
private WormChase wcTop;

public Obstacles(WormChase wc)
{ boxes = new ArrayList();
wcTop = wc;
}

synchronized public void add(int x, int y)
{
boxes.add( new Rectangle(x,y, BOX_LENGTH, BOX_LENGTH));
wcTop.setBoxNumber( boxes.size() ); // report new number of boxes
}

synchronized public boolean hits(Point p, int size)
// does p intersect with any of the obstacles?
{
Rectangle r = new Rectangle(p.x, p.y, size, size);
Rectangle box;
for(int i=0; i < boxes.size(); i++) {
box = (Rectangle) boxes.get(i);
if (box.intersects®)
return true;
}
return false;
} // end of intersects()

synchronized public void draw(Graphics g)
// draw a series of blue boxes
{
Rectangle box;
g.setColor(Color.blue);
for(int i=0; i < boxes.size(); i++) {
box = (Rectangle) boxes.get(i);
g.fillRect( box.x, box.y, box.width, box.height);
}
} // end of draw()

synchronized public int getNumObstacles()
{ return boxes.size(); }

} // end of Obstacles class
[/code]

Estou tentando entender este sync

“garantir o sincronismo de meuMetodo quando ele for executado por threads.
Read more: http://javafree.uol.com.br/topic-4966-Como-usar-synchronized.html#ixzz2CLB0Uasm

O que isso quer dizer?
Se tiver mais de uma thread tentando acessar o método, ele nao consegue ? Só uma thread por vez?
È isso ?

Exatamente. Digamos, por exemplo, que duas Threads diferentes tentem chamar o método add para um dado objeto. Como é o método é synchronized, uma Thread terá de esperar que a Thread que chamou o método primeiro termine a execução do mesmo.
A finalidade do synchronized é evitar que você tenha problemas com estados indeterminados em um programa. Suponha que você tivesse um método para remover elementos do ArrayList boxes. Se esse método não fosse synchronized, poderia ocorrer de você ter duas Threads tentando remover o mesmo objeto do ArrayList, o que provocaria problemas inesperados.

Só um comentário de estilo. Normalmente escrevemos a palavra synchronized após o modificador de visibilidade, não antes:

public synchronized void meuMetodo()

Fala André, tudo tranquilo?

Então cara, o uso de synchronized em um método garante que a execução deste método seja realizada apenas por uma Thread por vez, utilizando um mecanismo de lock. A Thread que começa a executar o método “pega” o lock, liberando-o ao término da execução do método. Threads que não possuem o lock devem aguardar a liberação para poder invocar o método.

É importante lembrar que o synchronized funciona de modo diferente dependendo da maneira como é utilizado. O Java atualmente permite 3 modos de sincronização de código:

public synchronized void foo() { }
Esta versão de foo() é um método de instância, ou seja, threads diferentes podem invocar foo() simultaneamente desde que as chamadas sejam realizadas em instâncias diferentes. O lock é feito na instância em que foo() foi invocado.

public static synchronized void foo() { }
Já esta versão de foo() só pode ser executada por uma Thread por vez, pois o lock é feito no objeto Class do tipo em que foo() foi invocado.

Por último o Java ainda permite o uso de blocos synchronized:

public void foo() { synchronized(user) { .... } }
Neste caso, a política de execução vai depender do objeto passado no bloco. Se for de instância, a trava é feita na instância. Se for um atributo estático, a trava é feita no objeto Class. Ela te permite uma liberdade maior por permitir que apenas uma porção do método seja sincronizada.

Atente-se que tudo isso é válido dentro de uma instância de JVM. Se a aplicação possuir 2 ou mais JVMs rodando em paralelo, um lock na JVM A não interfere na JVM B. Cada JVM possui seus próprios “locks”. Espero ter ajudado e por favor, me corrijam se disse alguma coisa errada :wink:

Abraço,

10 curtidas