I did a search here and found nothing to finish my doubts, with that, I hope someone can help me. I'll put the code here, so you can better visualize the problem. Oh, any suggestion of organization of the code and who has responsibility for what is very welcome too.
The problem is as follows:
Processes can use as many resources as they want, but can not be resources that are already in use or that the process has used before. At any given time, the code the way it is, enters deadlock and only one feature is released, then it remains in the check.
package com.alane.so;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.Semaphore;
public class Processo extends Thread{
private int id;
private int tempoSolicitacao;
private int tempoUtilizacao;
private SistemaOperacional sistemaOperacional;
private ArrayList<Recurso> recursosEmUsoNoProcesso;
private static final int MAX_PROCESSOS = 10;
//private static Semaphore totalDeProcessos = new Semaphore(MAX_PROCESSOS);
private static Semaphore mutexAdd = new Semaphore(1);
private static Semaphore mutexRemove = new Semaphore(1);
private ArrayList<Integer> memoriaDeProcessos;
public Processo(SistemaOperacional so, int id, int tempoSolicitacao, int tempoUtilizacao) {
this.id = id;
this.sistemaOperacional = so;
this.tempoSolicitacao = tempoSolicitacao;
this.tempoUtilizacao = tempoUtilizacao;
//this.mutexControleDisponibilidade =
this.recursosEmUsoNoProcesso = new ArrayList<Recurso>();
this.memoriaDeProcessos = new ArrayList<Integer>();
}
@Override
public void run() {
/*
* Aqui a gente vai dormir o tempo da solicitação.
* A cada dormida a gente solicita novo recurso e
* iniciamos uma nova Thread que conta o tempo de
* utilização. Apos essa contagem o recurso deixa
* de ser usado e fica livre.
*/
super.run();
do{
try {
Thread usando = new Thread(new Runnable() {
@Override
public void run() {
try {
int number = solicitarRecurso();
System.out.println(id + " Solicitei o number + " +number);
Recurso recurso = sistemaOperacional.retornaRecurso(number);
System.out.println(id +" Que é o recurso : " + recurso.getNome());
mutexAdd.acquire();
if(sistemaOperacional.verificaDisponibilidade(recurso) && verificaMemoriaDeProcessos(recurso)) {
usarRecurso(recurso);
}
mutexAdd.release();
sleep(tempoUtilizacao*1000);
//mutexControleDisponibilidade.release();
mutexRemove.acquire();
liberarRecurso(recurso);
mutexRemove.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
usando.start();
sleep(this.tempoSolicitacao*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}while(true);
}
public void usarRecurso(Recurso recurso) {
sistemaOperacional.getRecursosEmUso().add(recurso);
recursosEmUsoNoProcesso.add(recurso);
memoriaDeProcessos.add(recurso.getId());
System.out.println(id +" Oba, to usando recurso "+recurso.getNome());
}
public void liberarRecurso(Recurso recurso) {
sistemaOperacional.getRecursosEmUso().remove(sistemaOperacional.getRecursosEmUso().indexOf(recurso));
recursosEmUsoNoProcesso.remove(recursosEmUsoNoProcesso.indexOf(recurso));
System.out.println(id +" Liberar o recurso: " + recurso.getNome());
}
public int solicitarRecurso() {
//this.sistemaOperacional.getRecursosDisponiveis().size();
int number = new Random().nextInt(this.sistemaOperacional.getRecursos().size());
return number;
}
public boolean verificaMemoriaDeProcessos(Recurso recurso) {
if(memoriaDeProcessos.contains(recurso.getId())) {
System.out.println("Vish, você já usou o recurso: " + recurso.getNome());
return false;
}
return true;
}
public long getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getTempoSolicitacao() {
return tempoSolicitacao;
}
public void setTempoSolicitacao(int tempoSolicitacao) {
this.tempoSolicitacao = tempoSolicitacao;
}
public int getTempoUtilizacao() {
return tempoUtilizacao;
}
public void setTempoUtilizacao(int tempoUtilizacao) {
this.tempoUtilizacao = tempoUtilizacao;
}
public SistemaOperacional getSistemaOperacional() {
return sistemaOperacional;
}
public void setSistemaOperacional(SistemaOperacional sistemaOperacional) {
this.sistemaOperacional = sistemaOperacional;
}
}
package com.alane.so;
import java.util.ArrayList;
public class Recurso {
int id;
public static int recursosInstanciados = 0;
String nome;
static final int MAX_RECURSOS = 10;
public Recurso(String nome){
this.nome = nome;
this.id = recursosInstanciados;
recursosInstanciados++;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNome(){
return this.nome;
}
public static ArrayList<Recurso>recursosDefault(){
ArrayList<Recurso> recursos = new ArrayList<Recurso>();
recursos.add(new Recurso("Teclado"));
recursos.add(new Recurso("Mouse"));
//recursos.add(new Recurso("Placa de video"));
//recursos.add(new Recurso("DVD"));
//recursos.add(new Recurso("Pendrive1"));
//recursos.add(new Recurso("Fax Molden"));
//recursos.add(new Recurso("Impressora"));
return recursos;
}
}
package com.alane.so;
import java.util.ArrayList;
public class SistemaOperacional extends Thread {
private ArrayList<Processo> processos;
private ArrayList<Processo> processosDeadlock;
private int tempoDeVerificacao;
private ArrayList<Recurso> recursos;
public ArrayList<Recurso> getRecursosEmUso() {
return recursosEmUso;
}
public void setRecursosEmUso(ArrayList<Recurso> recursosEmUso) {
this.recursosEmUso = recursosEmUso;
}
private ArrayList<Recurso> recursosEmUso;
public SistemaOperacional(){
this.recursosEmUso = new ArrayList<Recurso>();
this.recursos = new ArrayList<>();
this.recursos = Recurso.recursosDefault();
}
public Recurso retornaRecurso(int number) {
return this.getRecursos().get(number);
}
public boolean verificaDisponibilidade(Recurso recurso) {
if (this.getRecursosEmUso().contains(recurso)) {
System.out.println("Vish, esta usando o :" +recurso.getNome());
return false;
}
return true;
}
public ArrayList<Processo> getProcessos() {
return processos;
}
public void setProcessos(ArrayList<Processo> processos) {
this.processos = processos;
}
public ArrayList<Processo> getProcessosDeadlock() {
return processosDeadlock;
}
public void setProcessosDeadlock(ArrayList<Processo> processosDeadlock) {
this.processosDeadlock = processosDeadlock;
}
public int getTempoDeVerificacao() {
return tempoDeVerificacao;
}
public void setTempoDeVerificacao(int tempoDeVerificacao) {
this.tempoDeVerificacao = tempoDeVerificacao;
}
public ArrayList<Recurso> getRecursos() {
return recursos;
}
public void setRecursos(ArrayList<Recurso> recursosDisponiveis) {
this.recursos = recursosDisponiveis;
}
}
package com.alane.so;
public class Main {
public static void main(String[] args) {
SistemaOperacional so = new SistemaOperacional();
Processo p = new Processo(so, 1, 1, 5);
Processo p1 = new Processo(so, 2, 1, 5);
p.start();
//p1.start();
}
}