Упражнение по синхронизации и потокам - PullRequest
0 голосов
/ 18 ноября 2018

Я делаю простое упражнение, чтобы понять концепцию потоков и синхронизации. Но я не знаю, правильный ли код или нет.

public class PopcornMachine {

    // shared resource
    private boolean isBinFull = false; 

    // producer method
    public synchronized void placePopcorn () throws InterruptedException { 
        while (true) {
            while (!isBinFull) wait ();
            isBinFull = true;
            System.out.println(isBinFull);
            notify ();
            Thread.sleep(1000);
        }
    }

    // consumer code
    public synchronized void takePopcorn () throws InterruptedException {
        while (true) {
            while (isBinFull) wait ();
            isBinFull = false;
            System.out.println(isBinFull);
            notify ();
            Thread.sleep(1000);
        }
    }
}

public class PopcornDemo {
    public static void main (String[] args) throws InterruptedException{
        final PopcornMachine machine = new PopcornMachine();

        Thread produce = new Thread (new Runnable() { 
            public void run() { 
                try { 
                    machine.placePopcorn (); 
                } catch(InterruptedException e) {}                 
            }
        }); 

        Thread consume = new Thread (new Runnable() { 
            public void run() { 
                try { 
                    machine.takePopcorn (); 
                } catch(InterruptedException e) {} 
            }
        }); 

        produce.start();
        consume.start();

        produce.join();
        consume.join();
    }
}

У меня есть ответ: ложный ложный ложный ложный ложный ложь

Но это неправильно. Разве не истинное значение должно прийти в середине кода?

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

с использованием synchronised на уровне самого метода гарантирует, что одновременно выполняется только один поток. Ключевое слово
synchronised принимает lock на объекте, к которому оно относится, т. Е. machine в вашем случае, и, следовательно, код не является правильной реализацией проблемы производителя-потребителя.

0 голосов
/ 18 ноября 2018

Измените условие while, как показано ниже, и посмотрите на комментарии. С вашим текущим кодом производитель никогда не выполняет.

Почему? потому что isBinFull изначально имеет значение false и ложно для потребителя тоже

и внутри вашего кода производителя

while (!isBinFull) wait (); 

никогда не станет false и будет ждать внутри цикла while.

Измените код, как показано ниже

 public synchronized void placePopcorn () throws InterruptedException { 
        while (true) {
            while (isBinFull) wait(); //Look here, waiting since bin is full
            isBinFull = true;
            System.out.println(Thread.currentThread().getName() + ":"+isBinFull);
            notifyAll ();
            Thread.sleep(500);
        }
    }

    // consumer code
    public synchronized void takePopcorn () throws InterruptedException {
        while (true) {
            while (!isBinFull) wait(); ////Look here, waiting since bin is not full
            isBinFull = false;
            System.out.println(Thread.currentThread().getName() + ":"+isBinFull);
            notifyAll ();
            Thread.sleep(500);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...