Как работает while l oop внутри класса writer и reader? Как поток изменяет переменную `empty`? - PullRequest
0 голосов
/ 04 мая 2020

Я изучал многопоточность в java и наткнулся на этот пример -

package com.practice.multithreading;

import java.util.Random;

public class DeadlockMain {
    public static void main(String[] args) {
        Message message = new Message();
          (new Thread(new Writer(message))).start();
          (new Thread(new Reader(message))).start();
    }
    }


class Message {
    private String message;
    private boolean empty = true;

    public synchronized String read() {
        while(empty) {
            try {
                wait();
            } catch(InterruptedException e) {
            }
        }
        empty = true;
        notifyAll();
        return message;
    }

    public synchronized void write(String message) {
        while(!empty) {
            try {
                wait();
            } catch(InterruptedException e) {
            }
        }
        empty = false;
        this.message = message;
        notifyAll();
    }
}

class Writer implements Runnable {
    private Message message;

    public Writer(Message message) {
        this.message = message;
    }

    public void run() {
        String messages[] = {
                "Humpty Dumpty sat on a wall",
                "Humpty Dumpty had a great fall",
                "All the king's horses and all the king's men",
                "Couldn't put Humpty together again"
        };

        Random random = new Random();

        for(int i=0; i<messages.length; i++) {
            message.write(messages[i]);
            try {
                Thread.sleep(random.nextInt(2000));
            } catch(InterruptedException e) {

            }
        }
        message.write("Finished");
    }
}

class Reader implements Runnable {
    private Message message;

    public Reader(Message message) {
        this.message = message;
    }

    public void run() {
        Random random = new Random();
        for(String latestMessage = message.read(); !latestMessage.equals("Finished");
            latestMessage = message.read()) {
            System.out.println(latestMessage);
            try {
                Thread.sleep(random.nextInt(2000));
            } catch(InterruptedException e) {

            }
        }
    }
}

Насколько я понимаю, -

  • Когда thread вызывает write метод,
  • переменная empty равна true, поэтому while(!true) => false,
  • пропускает, а l oop устанавливает empty=false,
  • , а затем this.message=message,
  • следующая итерация for loop, while(!false)=> true
  • Нет управления находится внутри while loop,

    Теперь я не могу найти где-нибудь внутри этого цикл / или в потоке, вызывающий метод empty, переменная имеет значение от set до true, так что управление выходит из while loop. Так как threads изменить переменную empty и написать и прочитать сообщения ??

Может кто-нибудь, пожалуйста, объясните мне несколько итераций этого кода?

Это очень помогло бы мне. Заранее спасибо!

1 Ответ

1 голос
/ 04 мая 2020

Вы можете рассматривать класс сообщений как буфер для одного сообщения. Когда вы пишете сообщение, оно становится полным и не может принимать новые сообщения, пока сообщение не будет прочитано. Точно так же, если вы читаете сообщение, когда оно пустое, оно ждет, пока кто-то записывает в него.

Экземпляры сообщения начинаются пустыми, поэтому, когда вы пишете в него, оно пропускает время, пока l oop устанавливает сообщение и уведомляет всех ожидающих читателей.

Еще одна запись перед тем, как чтение теперь ожидает в то время как l oop, потому что empty имеет значение false.

Если вы читаете сообщение из потока и если сообщение непустое, read пропускает время, пока l oop, устанавливает empty в true и уведомляет всех ожидающих авторов.

Когда писатель просыпается, он видит, что empty - истина, пишет сообщение и снова устанавливает empty в false.

...