Gerenciador da Área Crítica:

        Basicamente, uma classe que implemente uma gerência de memória crítica deve possuir uma referência à porção crítica da memória (ou a própria variável, no nosso caso).

        A sincronização através de monitores dá-se com a adição da palavra-chave synchronized aos métodos que devem ter exclusão mútua, e o uso de variáveis de condição, para determinar as situações de chaveamento.

        O conceito de monitores foi especialmente implementado em Java para atender também a uma necessidade da própria linguagem de programação. Como Java roda numa máquina virtual, os programas em Java devem compartilhar a memória destinada ao processo da máquina virtual, e assim o uso de monitores na implementação da própria linguagem tornou-se uma facilidade que foi estendida também para a programação.

        Abaixo pode-se ver os detalhes principais da implementação do gerenciador da memória crítica. Nota: as chamadas try-catch são empregadas para fazer o tratamento de exceções. Certos métodos (tais como o wait() e o notify()) exigem que haja tratamento de exceções, no caso de serem interrompidos por outra chamada de outro processo.


// Classe Buffer...

class B {

    private int Elemento_Critico=0; // área crítica
    private boolean full=false, empty=true; // variáveis de condição
    private int Lenght; // tamanho do buffer

    // método sincronizado que incrementa o buffer
    public synchronized void sub() {
        while (empty == true) { // testa condições
            try {
                wait(); // vai dormir
            } catch (InterruptedException e){
                return;
            }
        }
        --Elemento_Critico;
        if (Elemento_Critico==0) {
            empty = true;
        }
        if (Elemento_Critico==(Lenght-1)) {
            full = false;
            notify(); // acorda o primeiro processo da fila que estiver esperando
        }
    }

    public synchronized void add () {
    while (full == true) {
        try {
            wait(); // vai dormir
        } catch (InterruptedException e){
            return;
        }
    }
    ++ Elemento_Critico;
    if (Elemento_Critico == Lenght) {
        full = true;
    }
    if (Elemento_Critico==1) {
        empty = false;
        notify(); // acorda o primeiro processo da fila que estiver esperando
    }
}