【问题标题】:Monitors in Java two printers用 Java 监控两台打印机
【发布时间】:2018-02-26 09:47:41
【问题描述】:

我已经实现了两台打印机无法同时打印的问题,例如打印机 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 上打印打印机同时进行,现在我尝试使用监视器来代替信号量。

【问题讨论】:

    标签: java multithreading semaphore monitors


    【解决方案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)

    免责声明:我不完全理解这个问题。对解决方案进行逆向工程会导致误解。

    【讨论】:

    • 编辑问题
    • 对不起,我还不清楚。列出预期的输出和不应该发生的输出会很有用。在这种情况下,特别是 System.out.println() 是原子的,因此不可能同时打印两个字母(行!)。我认为这个玩具问题太简单了。
    猜你喜欢
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多