Thread - Condition

0 respostas
ECO2004

Olá, pessoal!

Estou com uma dúvida com o uso do Condition, em threads.

package com.wilson.threads;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SynchronizedBuffer implements Buffer 
{
	//Lock é uma interface e ReentrantLock uma classe que a implementa. Lock serve
	//para obter acesso à exclusão mútua.
	private Lock accessLock = new ReentrantLock();
	
	//Criar condições para ler e gravar no buffer
	private Condition canWrite = accessLock.newCondition();
	private Condition canRead = accessLock.newCondition();
	
	//variável para receber o valor
	private int buffer = -1;
	//verifica se o buffer está cheio.
	private boolean full = false;
	
	public void set(int value) 
	{
		//antes de colocar valor no buffer, adquire acesso exclusivo ao buffer.
		accessLock.lock();
		
		try
		{
			//verifico se o buffer está cheio
			//se estiver full = true, entra no looping
			while(full)
			{
				//se entoru aqui, quer dizer que o buffer está cheio.
				//não pode continuar
				//Tem que adormecer a thread que quer escrever
				canWrite.await();//adormece e libera o lock
			}
			
			//caso não esteja cheio, coloque o valor no buffer			
			buffer = value;
			//Agora, o buffer está cheio: tem apenas um lugar.
			full = true;
			//Se está cheio, então desperte o consumidor, representado por read.
			canRead.signal();
		}
		
		catch(InterruptedException e)
		{
			e.printStackTrace();
		}
		
		finally
		{
			accessLock.unlock();
		}
	}
	
	public int get() 
	{
		//var para receber o valor colocado por set
		int readValue = 0;
		//recebe acesso exclusivo ao buffer
		accessLock.lock();
		
		try
		{
			//o buffer está vazio
			while(!full)
			{
				//Se o buffer está vazio, não se pode ler dele
				//então, adormece a thread que quer ler.
				canRead.await();//adormece e libera o lock
			}
			
			//readvalue recebe o valor setado no método set
			readValue = buffer;
			//como o thread leitor já leu,
			//o buffer volta a ficar vazio
			full = false;
			//acorda o thread escritor
			canWrite.signal();			
		}
		
		catch(InterruptedException e)
		{
			e.printStackTrace();
		}
		
		finally
		{
			accessLock.unlock();
		}
		
		return readValue;
	}	

}

Nas linhas 14 e 15, eu faço o seguinte:

private Condition canWrite = accessLock.newCondition();   
    private Condition canRead = accessLock.newCondition();

Eu uso canWrite da seguinte forma. Se o produtor puder inserir dado na variável compartilhada, ele insere e depois dá um canRead.signal(), acordando o consumidor. Agora, o consumidor pode consumir dados. Se antes do consumidor consumir o dado o produtor tentar criar mais um dado, este é colocado para dormir e libera o lock.

O mesmo acontece com o consumidor, mas ao contrário.

Usei dois Condition: canWrite e canRead.
Eu não poderia usar apenas um Condition para Consumidor e para Produtor?

Produtor adquire lock.
Produtor verifica se buffer está vazio.
Produtor produz.
Produtor dá um signal em Condition condition (verifica-se agora apenas um Condition).
Produtor seta uma variável para não permitir produzir novamente antes da informação ser consumida.

Consumidor adquire lock.
Consumidor verifica se buffer está cheio.
Consumidor consome.
Consumidor dá um signal em Condition condition (mesmo do Produtor).
Consumidor seta uma variável para não permitir ler o mesmo valor duas vezes. Antes tem que ser produzido um novo valor.

Posso fazer assim? Retirar canRead e canWrite e colocar apenas um Condition condition?

Criado 14 de julho de 2011
Respostas 0
Participantes 1