How does the while loop inside writer and reader class works here ? How does the thread change the `empty` variable?

huangapple go评论76阅读模式
英文:

How does the while loop inside writer and reader class works here ? How does the thread change the `empty` variable?

问题

我正在学习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) {

            }
        }
    }
}

我的理解是--

  • 当一个线程调用write方法时,

  • empty变量为true,所以while(!true) => false

  • 跳过while循环,设置empty=false

  • 然后this.message=message

  • 下一个for循环的迭代,while(!false) => true

  • 不,控制权位于while循环内,

    现在我无法在循环内或调用方法中找到任何地方将empty变量设置为true,以使控制权退出while循环
    那么线程如何更改empty变量并读写消息?

有人能解释一下这段代码的几个迭代吗?

这对我将会是一个很大的帮助。提前谢谢!

英文:

I was learning Multithreading in java and came across this example--

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[] = {
&quot;Humpty Dumpty sat on a wall&quot;,
&quot;Humpty Dumpty had a great fall&quot;,
&quot;All the king&#39;s horses and all the king&#39;s men&quot;,
&quot;Couldn&#39;t put Humpty together again&quot;
};
Random random = new Random();
for(int i=0; i&lt;messages.length; i++) {
message.write(messages[i]);
try {
Thread.sleep(random.nextInt(2000));
} catch(InterruptedException e) {
}
}
message.write(&quot;Finished&quot;);
}
}
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(&quot;Finished&quot;);
latestMessage = message.read()) {
System.out.println(latestMessage);
try {
Thread.sleep(random.nextInt(2000));
} catch(InterruptedException e) {
}
}
}
}

My understanding is--

  • When a thread is calling the write method,

  • the empty variable is true so while(!true) =&gt; false ,

  • skips while loop sets empty=false,

  • then this.message=message,

  • next iteration of for loop,while(!false)=&gt; true

  • No the control is inside the while loop,

    Now i cannot find anywhere inside this loop/or in the thread calling method empty variable being set to true so that control comes out of while loop.
    So how does the threads change the empty variable and write and read the messages??

Can anyone pls explain me a few iterations of this code?

It would be of a great help to me.
Thanks in advance!

答案1

得分: 1

你可以将消息类比为一个单消息缓冲区。当你向其中写入一条消息时,它变满,直到消息被读取前无法接收新的消息。同样地,如果在消息为空时读取消息,它会等待直到有人写入为止。

消息实例初始为空,所以当你写入时,它会跳过 while 循环,设置消息,并通知任何正在等待的读取者。

如果在读取之前再次写入,则会在 while 循环处等待,因为 empty 为假。

如果你从一个线程中读取消息且消息非空,那么读取将跳过 while 循环,将 empty 设置为真,并通知任何正在等待的写入者。

当写入者被唤醒时,它会发现 empty 为真,然后写入消息,并将 empty 再次设为假。

英文:

You can think of the message class as a single-message buffer. When you write a message to it, it becomes full and cannot accept new messages until the message is read. Similarly, if you read the message when it is empty, it waits until someone writes to it.

Message instances start empty, so when you write to it, it skips the while loop, sets the message, and notifies any waiting readers.

Another write before the read now waits at the while loop, because empty is false.

If you read the message from a thread and if the message is nonempty, then read skips the while loop, sets empty to true, and notifies any waiting writers.

When the writer wakes up, it sees that empty is true, writes the message, and sets empty to false again.

huangapple
  • 本文由 发表于 2020年5月4日 23:30:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/61595873.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定