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?
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.