Мониторы на Java двух принтеров
Я реализовал проблему с двумя принтерами, из-за которой два принтера не могут печатать одновременно, например, принтер A печатает, а B не может, так же легко, как я сделал это с Semaphores
следующее:
мой Printer.class
похоже
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();
}
}
}
Тогда у меня есть класс, который разделяет переменную
class PrinterMachine{
public volatile Boolean canPrintA = true,canPrintB = true;
.... //Getter and Setter
И тогда у меня есть мой главный
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();
}
}
Это работает нормально, но мне интересно, как мне изменить мои семафоры для работы с monitors
вместо?
РЕДАКТИРОВАТЬ
Проблема?
У меня есть два принтера, и я не могу напечатать документ (System.out.println()) одновременно, поэтому я сделал программу с семафорами, чтобы сделать это, и с этим я не могу печатать на принтерах A и B на в то же время, и теперь я пытаюсь вместо использования семафоров сделать это с мониторами.
1 ответ
monitor
это то, что JVM делает для вас, когда вы используете старый добрый synchronized
кодовый блок / метод. Это будет выглядеть так:
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();
}
И внутри принтера:
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");
}
}
Приведенный выше блок кода гарантирует, что в synchronized(mutex)
кодовый блок. В вашем коде это было Semaphore mutex = new Semaphore(1);
Т.е. два принтера не могут быть там одновременно. Это легко, просто и не требует общей памяти.
С другой стороны, Semaphore multiplex = new Semaphore(2);
должен быть семафором. Вы можете использовать свой собственный счетчик и повторно внедрить Semaphore
, Это может быть ошибочным и медленным, потому что эти проблемы сложнее, чем кажется. Я предлагаю использовать Semaphore(2)
когда необходимо.
Отказ от ответственности: я не полностью понимаю проблему. Обратный инжиниринг решения приведет к недоразумениям.