Thread - método sleep()

Eu queria confirmar uma coisa sobre o método sleep de threads.

Se uma thread1 está em uma região crítica (um método qualquer) que é protegida por synchronized, dentro dessa região, se eu fizer, por exemplo,

Thread.sleep(1000);

essa minha thread1 libera temporariamente o bloqueio de monitor do objeto que estou protegendo, liberando a região crítica para outras threads?

Já tive essa dúvida, na epoca achei a resposta aqui.

http://www.coderanch.com/t/232096/threads/java/Thread-synchronized-run-method-sleep

e fiz os exemplos

Com sleep

[code]public class TesteRun implements Runnable {
public static void main(String[] args) {
TesteRun sr = new TesteRun();
Thread t1 = new Thread(sr);
t1.setName(“A”);
Thread t2 = new Thread(sr);
t2.setName(“B”);
t1.start();
t2.start();
}

public synchronized void run() {
	for (int i = 0; i < 10; i++) {
		System.out.println(Thread.currentThread().getName());
		try {
			Thread.sleep((int) (Math.random() * 1000));
		} catch (InterruptedException e) {
		}
	}
}

}[/code]

Com wait

[code]public class TesteRun implements Runnable {
public static void main(String[] args) {
TesteRun sr = new TesteRun();
Thread t1 = new Thread(sr);
t1.setName(“A”);
Thread t2 = new Thread(sr);
t2.setName(“B”);
t1.start();
t2.start();
}

public synchronized void run() {
	for (int i = 0; i < 10; i++) {
		System.out.println(Thread.currentThread().getName());
		try {
			this.wait((int) (Math.random() * 1000));
		} catch (InterruptedException e) {
		}
	}
}

}[/code]

Abs

Obrigado pela resposta!

Por que eu não consigo fazer Thread.wait() dentro do método que está protegido pelo synchronized?

Agora você me ferrou 8)
Vamos pensar juntos…
A classe Thread não fornece esse método de forma estática, só para o objeto…
A classe Thread cuida de todo o contexto de threads do programa, em um método(bloco, etc) synchronized você “isola” o objeto thread instanciado, então só ele mesmo pode “parar” sua ação.

Creio ser isso, não tenho certeza.

[quote=ECO2004]Obrigado pela resposta!

Por que eu não consigo fazer Thread.wait() dentro do método que está protegido pelo synchronized?[/quote]

[quote=Minduin]Agora você me ferrou 8)
Vamos pensar juntos…
A classe Thread não fornece esse método de forma estática, só para o objeto…
A classe Thread cuida de todo o contexto de threads do programa, em um método(bloco, etc) synchronized você “isola” o objeto thread instanciado, então só ele mesmo pode “parar” sua ação.

Creio ser isso, não tenho certeza.

[quote=ECO2004]Obrigado pela resposta!

Por que eu não consigo fazer Thread.wait() dentro do método que está protegido pelo synchronized?[/quote][/quote]

É isso mesmo…hehe

Eu estou com um programa que tem 3 threads. Uma insere em uma fila, outra retira e outra imprime os valores. Eu faço

thread1.start();
thread2.start();
thread3.start();

e as três threads começam a executar. Eu queria que, quando a thread1 colocasse o elemento 500 (capacidade máxima de 1000), ela liberasse o monitor e avisasse a thread3. Assim, a thread3 iria imprimir os elementos que têm na lista (imprimiria 500 elementos). Porém, na thread1, que coloca os elementos na lista, eu coloquei um if testando se o elemento é o de número 500 e dentro dele, faço um thread1.wait(). O que acontece é que está sendo lançado uma IllegalMonitorException.

Para garantir que a thread1 pega o monitor primeiro, eu coloquei as outras para dormirem por um tempo.

Por que a exceção está sendo lançada em thread1.wait() na linha 85?

package com.wilson.threads.fila;

import java.util.List;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Random;

public class Fila{
	
	private static List<Integer> lista = new ArrayList<Integer>();
	private static Random r = new Random();
	private final Thread thread1, thread2, thread3;
	
	public Fila(){
	
		thread1 = new Thread(
			new Runnable()
			{
				public void run()
				{						
					synchronized(lista){
						
						inserirLista();	
					}
				}
			});
		
		thread2 = new Thread(
				new Runnable()
				{
					public void run()
					{
						try{
							Thread.sleep(2000);
						}
						
						catch(InterruptedException e){
							
						}
						
						synchronized(lista){
							
							removerLista();	
						}								
					}
				});
		
		thread3 = new Thread(
				new Runnable()
				{
					public void run()
					{					
						try
						{
							Thread.sleep(1000);
						}
						
						catch(InterruptedException e){
							
						}
						
						synchronized(lista){
								
							imprimirLista();	
						}
					}
				});
		
		thread1.start();
		thread2.start();
		thread3.start();

	}
	
	public void inserirLista(){
		
		for(int i = 0; i < 1000; i++){
			lista.add(i, i);
			
			if(i == 500){
				
				try{
					
					thread1.wait();	
					thread3.notify();
					break;
				}
				
				catch(InterruptedException e){
					
					e.printStackTrace();
				}
				
			}
		}
	}
	
	public void removerLista(){
	
		ListIterator<Integer> it = lista.listIterator();
		
		while(it.hasNext()){
			it.next();
			it.remove();
		}
	}
	
	public void imprimirLista(){
	
		ListIterator<Integer> it = lista.listIterator();
		
		while(it.hasNext()){
			System.out.print(it.next()+" ");
		}
		
		if(lista.isEmpty()){
			System.err.println("Lista vazia!");
		}
	}

	public static void main(String[] args) {
		
		new Fila();
	}

}