[Duvida cruel] Synchronized e Static

6 respostas
C

PessoALL, estava estudando numa questao do simulador SyBex:

[IMG]http://img.photobucket.com/albums/v178/c0m4nch3/thread.jpg[/IMG]

CODE BOX:

class Classy {

	synchronized void notStaticMethod(){ 
		for (long n=0 ; n<1000000000L ; n++){
			System.out.println(n);
		}
	}
	
	static synchronized void StaticMethod(){ 
		for (long n=0 ; n<1000000000L ; n++){
			System.out.println(n);
		}
	}
}

Então, resolvi testar este problema no eclipse implementado os codigos a seguir:

class Classy extends Thread{

	synchronized void notStaticMethod(){ // Sem estatico, eh sincronizado com apenas objeto
		for (long n=0 ; n<10L ; n++){
			System.out.println(n + Thread.currentThread().getName());
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	static synchronized void StaticMethod(){ // Com estatico, eh sincronizado com classe Classy
		for (long n=0 ; n<10L ; n++){
			System.out.println(n + Thread.currentThread().getName());
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

public class Questao30 extends Thread{
	
	Classy classy1 = new Classy();
	Classy classy2 = new Classy();
	
	public static void main (String args[]){
		
		Questao30 a = new Questao30();
		Questao30 b = new Questao30();
		a.setName("A");
		b.setName("B");
		
		a.start();
		b.start();	
	}
	
	public void run(){
		
		if(Thread.currentThread().getName().equals("A")){
			classy1.notStaticMethod();
		}
		
		if(Thread.currentThread().getName().equals("B")){
			classy1.notStaticMethod();
		}
	
	}
}

Então, segundo do SyBex, as respostas corretas sao A, B e D. Mas fiz teste assim:

* Thread A executando classy1.notStaticMethod() e Thread B executando classy1.notStaticMethod()

e o Eclipse executou e nao estao sincronizados!!!

6 Respostas

giovaniufop

Você esta questionando a resposta D, não é?

Repare que o metodo nonStaticMethod() é synchronized, isso quer dizer que se uma thread A esta executando o método de uma instancia, uma Thread B não poderá executar o método (da mesma instância) até que A termine.

Repare no que diz a alternativa D:

Se uma thread A está executando classy1.nonStaticMethod() uma thread B não pode executar classy1.nonStaticMethod();

Repare na alternativa que as duas threads estão acessando a mesma instancia classy1 B nesse caso não está acessando classy2, ou seja, duas threads querendo acessa um UNICO METODO. Então B terá que esperar A terminar o método synchronized nonStaticMethod.

Se a alternativa dissesse que:

Se uma thread A está executando classy1.nonStaticMethod() e B estiver executando classy2.nonStaticMethod() (repare que são instãncias diferentes agora, classy1 e classy2, então temos 2 metodos diferentes em instancias diferentes) ENTÃO B poderia executar o método nonStaticMethod() pois são métodos de instancias diferentes.

ENTENDEU?

giovaniufop

E mais uma coisa, na sua implementação existem 4 objetos diferentes de Classy.

Você colocou :

Classy classy1 = new Classy();
Classy classy2 = new Classy();

Assim quando vc cria a Thread A, ela cria dois objetos, e quando cria a Thread B cria mais dois objetos.
Eu acho que o exercicio quis dizer que tanto em A como em B existem duas referencias que apontam para os mesmos 2 objetos.

Se eu entendi corretamente.

Mas é uma bagunça msm kra, a gnt começa ler e começa entender, dps acha que não entendeu, é complicado.
Acho que minha interpretação está correta, mas se alguem achar errado por favor comente o topico pra gnt chegar numa solução.

C

giovaniufop, eu já estava certo o que voce explicou. Mas estou falando dos meus codigos testando a resposta D porque não estao sincronizados no eclipse!

Então, tambem acho que estes codigos foram mal feitos…, ou seja, nao foram implementados corretamente…alguma solução?

Obrigado por responder

Link_pg

Olá!

Lembrando também que ao sincronizar um método static o bloqueio fica na CLASSE e não no OBJETO…

class A{
    synchronized static void a(){} //aqui o que é bloqueado é o A.class
    synchronized void b(){} //aqui o que é bloqueado é this
}

Abraços

Java_Player

onde você colocou:

Classy classy1 = new Classy(); Classy classy2 = new Classy();

mude para:

static Classy classy1 = new Classy(); static Classy classy2 = new Classy();

Aí sim vão ficar só dois objetos Classy, que vão ser compartilhados pelas duas threads.

C

Link_pg, eu sei qual a diferenca entre sem e com static dos metodos, pois coloquei os meus comentarios nos codigos. Mas vlw pela explicação

Java Player, eh isso mesmo. Bem simples.

Criado 17 de março de 2008
Ultima resposta 19 de mar. de 2008
Respostas 6
Participantes 4