Traffic Light: Deadlock detection problems

Asked

Viewed 285 times

3

I did some research around here and I couldn’t find anything to end my doubts, so hopefully someone can help me. I’m going to put the code here, so you can visualize the problem better. Ah, any suggestion of code organization and who has responsibility for what is very welcome too.

The problem is this:

Processes can use as many resources as they want, but it cannot be resources that are already in use or that the process has used before. At a given moment, the code as it stands, goes into 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();
    }
}
  • Have you ever used your IDE’s Debugger? You’re using these printlns there to know, at runtime, what’s going on. I advise you to use the Debugger. Finding bugs in threaded programs is pretty tricky just looking at the code, if you debug it then you’ll find it fast.

  • Actually, using debug for a threaded program doesn’t work very well. The IDE is usually lost. In other cases, when you are in debug the application works correctly and when you run it gives the error. In such cases the ideal is to debug really using prints.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.