简体   繁体   中英

Monitors in Java two printers

I've implemented a problem with two printers that two printers can not print at the same time, for example printer A is printing and B can not, as easy as it, I did it with Semaphores as follows :

My Printer.class looks like

public class Printer extends Thread {

    Semaphore mutex,multiplex;
    PrinterMachine printerMachine;
    String printer = "";
    public Printer(Semaphore mutex, Semaphore multiplex, PrinterMachine pm) {
        this.multiplex = multiplex;
        this.mutex = mutex;
        printerMachine = pm;
    }
    @Override
    public void run() {
        String printer = "";
        for(;;) {
            try {multiplex.acquire();} catch (InterruptedException e) {}
            try {mutex.acquire();} catch (InterruptedException e) {}
            if(printerMachine.getCanPrintA()) {
                printer = "A";
                printerMachine.setCanPrintA(false); 
            }
            else {
                printer="B";
                printerMachine.setCanPrintB(false); 
            }
            mutex.release();
            try {Thread.sleep(100);} catch (InterruptedException e) {}
            System.out.println(printer);
            if(printer.equals("A")) {
                printerMachine.setCanPrintA(true);
                }
            else {
                printerMachine.setCanPrintB(true);
            }
            try {Thread.sleep(100);} catch (InterruptedException e) {}
            multiplex.release();
        }
    }

}

Then I have a class that shares a variable

class PrinterMachine{
    public volatile Boolean canPrintA = true,canPrintB = true;
.... //Getter and Setter

And then I have my main

public static void main(String[] args) {
        Semaphore mutex = /* COMPLETE */ new Semaphore(1);
        Semaphore multiplex = /* COMPLETE */ new Semaphore(2);
        PrinterMachine pm = new PrinterMachine();

        Printer printers[] = new Printer[10];
        for (int i = 0 ; i<printers.length; i++) {
            printers[i] = new Printer(mutex,multiplex,pm);
            printers[i].start();
        }   
        try {
            Thread.sleep(5000);
        }
        catch(InterruptedException ie) {}
        for (int i = 0 ; i<printers.length; i++) {
            printers[i].stop();
        }
    }

It is working ok, but I'm wondering how do I change my semaphores to work with monitors instead?


EDIT

Problem?

I have two printers and I can not print a document (System.out.println()) at the same time, so I did a program with Semaphores to do this, and with that I can not print on A and B printers at the same time, and now I'm trying to instead of using Semaphores do it with Monitors.

The monitor is something that the jvm does for you when you use the good old synchronized code block / method. This would look like this:

Object mutex = new Object(); // it can be any object, even a class.
                             // However, it's preferred to have a separate class only for this.
for (int i = 0 ; i<printers.length; i++) {
    printers[i] = new Printer(mutex, pm); // object sharing the mutex object
    printers[i].start();
}

And within a printer:

public class Printer extends Thread {
    private final Object mutex;
    // ..

    public Printer (Object mutex, ...) {
        this.mutext = mutex;
    }

    @Override
    public void run() {
        synchronized(mutex) { //all Printers synchronize the same object
            System.out.println("A");
        }
    }

The code block above makes sure that only one printer can be in the synchronized(mutex) code block. In your code that was Semaphore mutex = new Semaphore(1); Ie two printers can not be there at the same time. This is easy, simple, and no shared memory is required.

On the other hand, the Semaphore multiplex = new Semaphore(2); must be a semaphore. You might use your own counter and re-implement Semaphore . That's likely to be buggy and slow because these problems are more complicated than they seem to be. I suggest to use Semaphore(2) when necessary.

Disclaimer : I don't fully understand the problem. Reverse-engineering the solution would lead to misunderstandings.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM