Problemas no Produtor x Consumidor

Pessoal Boa Tarde!

Estou com 2 problemas no minha implementação do Produtor x Consumidor, Estou usando uma Fila.
1° - Preciso implementar o Produtor de forma que os valores produzidos sejam lidos do teclado, porém quando faço isso, parece que o Consumidor pára de funcionar, . Já quando eu mando gerar os valores aleatoriamente, as duas Threads funcionam normalmente.

2° - Na hora de mostrar a execução das duas Threads, preciso mostrar os valores produzidos e apagar os valores consumidos, mas ainda não encontrei nenhuma forma eficaz de se fazer isso.

Será que alguém poderia me ajudar nesses dois problemas ?

PS: O código já está 90 % concluído, faltando apenas esses dois problemas para resolver.

Segue o código:

[code]import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Produtor extends Thread {

//Valor a ser armazenado
private int valor;

//Estrutura de dados responsável pelo armazenamento dos valores.
Queue<Integer> dados;

public Produtor(Queue<Integer> dados) {
	this.valor = 0;
	this.dados = dados;
}

/*Metodo para mostrar os valores armazenados sem removê-los dos dados*/
private void mostrarSemRemover(Queue<Integer> dados) {
	
	Queue<Integer> ftemp = new LinkedList<Integer>();
	
	while(!this.dados.isEmpty()) {
		int temp = this.dados.remove();
		System.out.print("<" + temp + ">");
		ftemp.add(temp);
	}
	
	while(!ftemp.isEmpty()) {
		this.dados.add(ftemp.remove());
	}
}

/*Metodo para produzir os valores*/
private void produzir() {
	
	synchronized (dados) {
		
		/*Leitura dos valores do teclado*/
		Scanner sc = new Scanner(System.in);
		this.valor = sc.nextInt();
		
		/*Exemplo com numeros gerados aleatoriamente*/
		/*this.valor = (int)(Math.random() * 10000);*/
		
		/*Adicionando os valores ao dados*/
		dados.add(valor);
		this.mostrarSemRemover(dados);
		
		//Disparar aviso de atualização dos dados
		dados.notifyAll();
	}//fim sync()
}//fim produzir()

public void run() {
	
	while(true) {
		
		this.produzir();
		
		try {
			Thread.sleep((int)Math.random() * 5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}//fim while	
}//fim run()

}//fim class Produtor[/code]

[code]import java.util.LinkedList;
import java.util.Queue;

public class Consumidor extends Thread {

Queue<Integer> dados;

public Consumidor(Queue<Integer> dados) {
	this.dados = dados;
}

private void consumir() {
	
	synchronized (dados) {
		/*Verifica se existem itens nos dados*/
		if(dados.size() > 0) {
			
			int valor = dados.remove();
			System.out.print("(" + "  " + ")");
			
		}//fim if
		else {
			/*Caso não existam itens no dados*/
			try {
				/*Espera o produtor notificar que houve uma reposição*/
				dados.wait();
				
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}//fim else
	}//fim sync()
}//fim consumir()

public void run() {
	
	while(true) {
		
		this.consumir();
		
		try {
			Thread.sleep((int)Math.random() * 5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}//fim while
}//fim run()

}//fim class Consumidor[/code]

[code]import java.util.LinkedList;
import java.util.Queue;

public class Principal {

public static void main(String[] args) {

	/*Local de armazenamento dos itens*/
	Queue<Integer> dados = new LinkedList<Integer>();
	
	/*Criação do Produtor*/
	Produtor prod = new Produtor(dados);
	
	/*Criação do Consumidor*/
	Consumidor cons = new Consumidor(dados);
	cons.setPriority(Thread.MIN_PRIORITY);
	
	/*Inicialização das Threads*/
	prod.start();
	cons.start();	
}

}
[/code]