1

2台のプリンターが同時に印刷できないという問題を2台のプリンターで実装しました。たとえば、プリンター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正常に動作していますが、代わりにセマフォを変更するにはどうすればよいですか?


編集

問題?

私は 2 台のプリンターを持っていますが、ドキュメント (System.out.println()) を同時に印刷することはできません。そのため、これを行うためにセマフォを使用してプログラムを作成しました。同時に、セマフォを使用する代わりにモニターを使用しようとしています。

4

1 に答える 1

0

これは、古き良きコードブロック/メソッド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");
        }
    }

上記のコード ブロックは、コード ブロック内に 1 つのプリンターしか存在できないことを確認しsynchronized(mutex)ます。あなたのコードでは、つまりSemaphore mutex = new Semaphore(1);2 つのプリンターが同時に存在することはできません。これは簡単でシンプルで、共有メモリは必要ありません。

一方、 はSemaphore multiplex = new Semaphore(2);セマフォでなければなりません。独自のカウンターを使用して再実装することもできますSemaphore。これらの問題は見た目よりも複雑であるため、バグが多く、遅くなる可能性があります。必要に応じて使用することをお勧めしますSemaphore(2)

免責事項: 私は問題を完全には理解していません。ソリューションをリバース エンジニアリングすると、誤解が生じる可能性があります。

于 2018-02-26T12:50:43.277 に答える