Locks em casos de métodos estáticos e synchronized

2 respostas
A

Oi pessoal,

Estou com uma dúvida aqui. Estou estudando utilizando o livro da Kathy, e ‘acho’ que entendi o que vou explicar, mas gostaria de confirmar com vcs para não ficar na dúvida…

Supondo uma classe, com 3 métodos synchronized, sendo 1 deles estático (código no final da mensagem).

Supondo também que eu tenho 3 threads, cada uma tentando acessar um dos diferentes métodos da primeira classe supondo que as 3 threads estão acessando os métodos de mesma instância (tirando a static que não é instanciado, mas é invocado com a mesma variável de referência dos outros objetos).

Thread 1 realiza acesso no método synchronized 1
Thread 2 realiza acesso no método synchronized 2
Thread 3 realiza acesso no método estático synchronized 3

Agora vamos às minhas dúvidas:

  • Enquanto a Thread 1 acessa o seu método synchronized 1, a thread 2 não consegue acessar o método syncronized 2, certo? (Lembrando que estamos falando da mesma instância)
  • É possível ter a thread 1 executando o método synchronized 1, e ao mesmo tempo a thread 3 executar o seu bloco synchronized estático 3, ou não? Nos meus testes aqui, aparentemente parece que sim, a menos que tenha feito coisa errada.
  • Se é possível a thread 3 e a thread 1 executarem seus métodos em paralelo, pode haver concorrência com as variáveis estáticas da classe, confere?

É isso mesmo, ou estou errado?

A seguir está o código que eu fiz para simular estas dúvidas:

class Metodos {
	static int s = 1;
	
	public synchronized void showOne() {
		System.out.println("--- START 1 ---");
		for(int i=0; i< 100000; i++) {for(int y=0; y< 5000; y++) {}}
		System.out.println("1" + s);
		System.out.println("--- ENDS  1 ---");
	}

	public synchronized void showTwo() {
		System.out.println("--- START 2 ---");
		for(int i=0; i< 100000; i++) {for(int y=0; y< 5000; y++) {}}
		System.out.println("2" + s);
		System.out.println("--- ENDS  2 ---");
	}
	
	public static synchronized void showStatic() {
		System.out.println("--- START STATIC ---");
		for(int i=0; i< 100000; i++) {for(int y=0; y< 5000; y++) {}}
		System.out.println("3" + s);
		System.out.println("--- ENDS  STATIC ---");
	}
}

class Tentativas extends Thread {

	int i;
	Metodos m;
	
	Tentativas(int i, Metodos m) {
		this.i = i;
		this.m = m;
	}
	
	public void run() {
		while(true) {
			if(i == 1)
				m.showOne();
			else if(i == 2)
				m.showTwo();
			else if(i == 3)
				m.showStatic();
			
		}
	}
}

public class Testes03 {
	public static void main(String[] args) {
		Metodos m = new Metodos();
		Tentativas t1 = new Tentativas(1, m);
		Tentativas t2 = new Tentativas(2, m);
		Tentativas ts = new Tentativas(3, m);
		
		t1.start();
		t2.start();
		ts.start();
	}
}

Desde já agradeço a ajuda pessoal, um abraço!

2 Respostas

victorwss

Correto.

É isso mesmo.

Sim.

Certo.
Basicamente cada Object contém uma trava intrínseca. Quando uma Thread entra em um método sincronizado, ela reserva essa trava para ela:synchronized (x) { /* A thread que executar isso será a dona da trava x neste trecho. */ }Se uma Thread tentar entrar em um bloco sincronizado e esta trava já estiver com outra Thread, esta Thread irá esperar até que a trava solicitada seja liberada.public synchronized void x() { // blabla }É o mesmo que:public void x() { synchronized (this) { // blabla } }Epublic static synchronized void x() { // blabla }É o mesmo que:public static void x() { synchronized (NomeDestaClasse.class) { // blabla } }

A

Jóia Victor, obrigado por ajudar :slight_smile:

Criado 7 de outubro de 2008
Ultima resposta 7 de out. de 2008
Respostas 2
Participantes 2