Gostaria de saber se alguém pode me ajudar e fazer uma comunicação entre processos distintos em FIFO. Basicamente um processo fica continuamente escrevendo e o outro lendo. Estou começando a programar em Java agora, não tem um mês. Se puderem indicar links,livros ou vídeos ajudaria bastante.
Comunicação FIFO
9 Respostas
Esse problema é conhecido como Produtor/Consumidor, é um clássico problema de concorrência.
Existem algumas maneiras diferentes de fazer comunicação entre duas JVMs. As duas maneiras mais fáceis:
- Socket
- RMI
Independente da maneira que você escolher para executar a comunicação, vai ter que montar um esquema de sincronia. Algumas ideias:
- Um “servidor” central mediador, aonde os produtores escrevem e os consumidores consomem (produtores e consumidores não se comunicam entre si). Dessa forma você pode escalar para quantos produtores/consumidores quiser.
- Fazer o produtor se comunicar diretamente com o consumidor. Dessa forma você pode ter vários produtores/consumidores também, porem cada consumidor vai ter sua própria fila de consumo.
Boa sorte!
EDIT: Não vi a parte que você falou que era iniciante. Essa atividade não é tão simples de se fazer, pois requer alguns conhecimentos de nível intermediário/avançado. Mas é totalmente fazível! Garanto que se você estudar o suficiente e concluí-la, vai saber mais do que muita gente que diz por aí que sabe! kkkkkkk
Não sei se você sabe inglês, mas ajudaria bastante, pois a gigantesca maioria do material de qualidade está nessa língua.
Um resuminho sobre RMI (tem uma trilha no site da oracle só sobre rmi, aqui):
RMI significa Remote Method Invocation. Funciona mais ou menos assim: Você tem uma interface, digamos assim:
public interface Calculator() {
double calculate();
}
Certo?
Você vai ter uma cópia dessa interface tanto no servidor quanto no cliente.
No servidor, você vai implementar um objeto que implementa essa interface, e vai registrar o teu programa como capaz de receber invocações RMI para a interface Calculator.
No cliente, você vai conectar no servidor através dos métodos de conexão do RMI, e vai dizer assim: “Ei, servidor, me dá uma implementação dessa interface aqui: Calculator.”
O servidor, que registrou que poderia atender chamadas RMI para essa interface, instancia o objeto que a implementa e manda de volta pela rede (isso tudo é automático, você não precisa se preocupar com essa parte).
No cliente, você recebe um objeto que implementa essa interface (você não sabe qual é, só tem a interface). Se você chamar o método calculate no cliente, na visão do cliente, é exatamente a mesma coisa de chamar o método de um objeto local, mas, na verdade, esse objeto é apenas um proxy para um objeto remoto (que está no servidor). É como se você invocasse o método no servidor, o servidor dá o return e você pega o retorno no cliente, tudo isso de forma quase totalmente transparente.
Uma outra dica:
Existe uma maneira extremamente simples de implementar a estrutura de dados para fazer a lógica da escrita/leitura funcionar.
Existe uma interface no Java, chamada de BlockingQueue. Ela é thread-safe, você pode acessa-la a partir de várias threads simultaneamente sem ter medo do programa quebrar, é basicamente o produtor/consumidor pronto kkkkkkkk.
Existem algumas implementações já prontas dessa interface, que já vem com o Java, como ArrayBlockingQueue.
Funciona assim:
- Se ela estiver vazia, na hora que você pedir o próximo objeto, a tua thread vai esperar até alguém escrever alguma coisa na estrutura. Quando isso acontecer, tua thread vai obter o objeto e continuar o trabalho normalmente;
- Se ela estiver cheia, na hora que alguém tentar escrever, vai ficar esperando abrir um espaço. A thread vai ficar dormindo (aguardando sua vez) mesmo, até a hora que abrir um espaço e finalmente ela poder escrever.
Esse processo é inteiramente transparente. O bloqueio acontece na hora que você chama o método de escrita/leitura se a escrita/leitura não puder ser feita por um motivo de estar cheia ou vazia.
Seria algo assim:
valor = calculaValor();
// até aqui a execução é normal.
// imagine que a fila está cheia
fila.escrever(valor);
// o método escrever simplesmente não vai retornar, vai ficar como se
// estivesse executando durante um tempão, até que abra um espaço na fila
// e a escrita possa ser feita.
// assim que a escrita é feita, o método escrever retorna e continua executando
// normalmente a próxima instrução.
fazAlgumaCoisa();
fazOutraCoisa();
O Produtor vai ficar escrevendo nessa estrutura e o consumidor consumindo.
kkkkkk Com esse Edit deu uma assustada. Mas conseguir pegar o que você quis dizer. Estou estudando através de dois livros pra Java e POO. Tipo, não sei se meu programa vai precisar dessa complexidade toda, ou eu não entendi direito. kkkkk Preciso fazer uma comunicação local com processos destintos, entendi que o cliente é um e o servidor é outro, mas você mencionou usar a rede para isso. É mesmo necessário? O que preciso é isso: Comunicação entre processos usando fifo ou pile:
um processo fica continuamente escrevendo e o outro lendo. Dessa atividade não entendi direito como farei a leitura e escrita em tempo de execução na memória Ram. Que é a memória que o FIFO usa. Se puder dar uma esclarecida agradeço.
Threads eu já usei, entendo como funciona. Mas neste caso preciso fazer com que a comunicação seja entre processos destintos. A thread executa no mesmo processo, não seria isso que procuro kkkkk
Então, se fosse em C, você poderia implementar comunicação entre processos utilizando memória compartilhada. Infelizmente não é possível fazer isso (não de forma simples, nunca tentei descobrir se dá pra “hackear” o esquema e implementar) entre duas JVMs diferentes por questão de segurança. Talvez alguém aqui do forum saiba como fazer isso (aguardemos, estou bem curioso para saber).
Tem uma thread no stack overflow que fala sobre isso, aqui.
O que o cara diz ali é que você pode simular isso, utilizando o disco ao invés da memória ram, com leitura/escrita de arquivos.
A outra solução que ele dá é socket.
Tem certeza que você precisa de 2 processos separados, e não duas threads dentro de um mesmo processo? A segunda alternativa é extremamente mais simples e não precisa de nada disso (socket, rmi ou arquivo).
Bom vou da uma pesquisada nessa questão de Socket. Cara estou vindo de C kkkkkk nunca tive aula em Java, e meu professor simplesmente pedi isso em Java valendo 10 kkkkk Estou numa corrida contra o tempo estudando solo. Ele pediu comunicação usando o HD, isso eu já fiz. Enquanto um processo ler o arquivo o outro escreve. Mas agora ele pedi pra usar a memória Ram. Em C, usaria memória alocada para isso, mas em Java estou um pouco perdido. Já usei Threads em C e em Java, agora é processos destintos mesmo kkkk Obrigado ae. Já deu uma esclarecida
Uma outra forma é utilizar os sockets do UNIX (se vc estiver usando um SO baseado em UNIX, claro). É basicamente um pipe entre dois processos locais. Além disso, não precisa ser necessariamente duas JVMs, dá pra ligar tecnologias diferentes também.
É mais rápido do que usar socket normal, só mais uma possibilidade
Boa sorte!
Estou usando sim amigo. Obrigado pela ajuda, foi bem útil. Vou pesquisar como fazer isso kkkkkkk! Vlw
Você pode utilizar um servidor de filas: RabbitMQ, ActiveMQ entre outros.
Ou pode procurar por Colletion Queue no Java.