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
monitoris something that the jvm does for you when you use the good oldsynchronizedcode block / method. This would look like this:And within a printer:
The code block above makes sure that only one printer can be in the
synchronized(mutex)code block. In your code that wasSemaphore mutex = new Semaphore(1);I.e. 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-implementSemaphore. That's likely to be buggy and slow because these problems are more complicated than they seem to be. I suggest to useSemaphore(2)when necessary.Disclaimer: I don't fully understand the problem. Reverse-engineering the solution would lead to misunderstandings.