Writer/Reader 使用监视器不工作
Writer/Reader using Monitor not working
我正在做一项作业,其中正在实施一个 Writer/Reader 问题,该问题使用监视器进行同步。
场景:编写器应一次将列表中的一个字符串写入缓冲区(缓冲区一次只能容纳一个字符串)。然后 reader 应该从缓冲区中读取字符串并在 gui 中打印字符串,打印之间有 0.5 秒的暂停。该程序使用一个单独的 writer-thread 和一个单独的 reader-thread,当按下 gui 中的一个按钮时它们会同时启动。
我的问题:我无法使同步工作,reader每 0.5 秒打印一次 null(这意味着当reader 尝试从中读取)。我设法找到一个错误:作者没有到达 buffer.put(text.get(i))
所在的 try
,但我不知道为什么。
谁能帮忙??非常感激!我的代码在下面,希望足够了,我不想垃圾邮件太多代码。 (我对 Writer/Reader 问题也很陌生,但已经阅读了一些编码示例等)
作者:
public void run() {
buffer.length(text.size());
for (int i = 0; i < text.size(); i++) { //loops thorugh the list of strings
System.out.println("hj"); //reaches this
try {
buffer.put(text.get(i)); //put the string into the buffer
System.out.println("put done"); // never reaches this
sleep(); //pauses the thread for 0.5 seconds
} catch (InterruptedException e) {
System.out.println("error"); //never reaches this either
e.printStackTrace();
}
}
}
缓冲区:
/**
* gets a string from the writer
* @throws InterruptedException
*/
public synchronized void put(String string) throws InterruptedException {
while(hasString == false) { //we only want to put a string into the buffer if it is empty
wait();
this.string = string;
hasString = true;
notify();
}
}
/**
* passes on a string to the reader
* @throws InterruptedException
*/
public synchronized String get() throws InterruptedException {
while(hasString == true) { //we only want to pass on a string if the buffer is NOT empty
wait();
hasString = false;
notify();
}
return string;
}
Reader:
/**
* reads a string from the buffer and writes it to the gui in the destination-tab
*/
public void run() {
for (int i = 0; i < buffer.getLength(); i++) { //loops through the length of the list with strings
try {
string = buffer.get(); //gets string from buffer
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//writes the string in the gui
sb.append(string);
GUIMonitor.txtPaneDest.setText(sb.toString());
try {
sleep(); //pauses the thread for 0.5 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
您可以尝试这个解决方案,只需在 while 块之外为 'hasString' 赋值。
/**
* gets a string from the writer
* @throws InterruptedException
*/
public synchronized void put(String string) throws InterruptedException {
while(hasString == false) { //we only want to put a string into the buffer if it is empty
wait();
}
this.string = string;
hasString = true;
notify();
}
/**
* passes on a string to the reader
* @throws InterruptedException
*/
public synchronized String get() throws InterruptedException {
while(hasString == true) { //we only want to pass on a string if the buffer is NOT empty
wait();
}
hasString = false;
notify();
return string;
}
代码现在可以工作(在@whaat 回答的帮助下),只需更改 Buffer-class 中的代码,同时保持 Writer 和 Reader 不变。我会在这里留下缓冲区的工作代码,以防其他人遇到和我一样的问题:)
/**
* gets a string from the writer
* @throws InterruptedException
*/
public synchronized void put(String string) throws InterruptedException {
while(hasString == true) { //we only want to put a string into the buffer if it is empty
wait();
}
this.string = string;
hasString = true;
notify();
}
/**
* passes on a string to the reader
* @throws InterruptedException
*/
public synchronized String get() throws InterruptedException {
while(hasString == false) { //we only want to pass on a string if the buffer is NOT empty
wait();
}
hasString = false;
notify();
return string;
}
我正在做一项作业,其中正在实施一个 Writer/Reader 问题,该问题使用监视器进行同步。
场景:编写器应一次将列表中的一个字符串写入缓冲区(缓冲区一次只能容纳一个字符串)。然后 reader 应该从缓冲区中读取字符串并在 gui 中打印字符串,打印之间有 0.5 秒的暂停。该程序使用一个单独的 writer-thread 和一个单独的 reader-thread,当按下 gui 中的一个按钮时它们会同时启动。
我的问题:我无法使同步工作,reader每 0.5 秒打印一次 null(这意味着当reader 尝试从中读取)。我设法找到一个错误:作者没有到达 buffer.put(text.get(i))
所在的 try
,但我不知道为什么。
谁能帮忙??非常感激!我的代码在下面,希望足够了,我不想垃圾邮件太多代码。 (我对 Writer/Reader 问题也很陌生,但已经阅读了一些编码示例等)
作者:
public void run() {
buffer.length(text.size());
for (int i = 0; i < text.size(); i++) { //loops thorugh the list of strings
System.out.println("hj"); //reaches this
try {
buffer.put(text.get(i)); //put the string into the buffer
System.out.println("put done"); // never reaches this
sleep(); //pauses the thread for 0.5 seconds
} catch (InterruptedException e) {
System.out.println("error"); //never reaches this either
e.printStackTrace();
}
}
}
缓冲区:
/**
* gets a string from the writer
* @throws InterruptedException
*/
public synchronized void put(String string) throws InterruptedException {
while(hasString == false) { //we only want to put a string into the buffer if it is empty
wait();
this.string = string;
hasString = true;
notify();
}
}
/**
* passes on a string to the reader
* @throws InterruptedException
*/
public synchronized String get() throws InterruptedException {
while(hasString == true) { //we only want to pass on a string if the buffer is NOT empty
wait();
hasString = false;
notify();
}
return string;
}
Reader:
/**
* reads a string from the buffer and writes it to the gui in the destination-tab
*/
public void run() {
for (int i = 0; i < buffer.getLength(); i++) { //loops through the length of the list with strings
try {
string = buffer.get(); //gets string from buffer
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//writes the string in the gui
sb.append(string);
GUIMonitor.txtPaneDest.setText(sb.toString());
try {
sleep(); //pauses the thread for 0.5 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
您可以尝试这个解决方案,只需在 while 块之外为 'hasString' 赋值。
/**
* gets a string from the writer
* @throws InterruptedException
*/
public synchronized void put(String string) throws InterruptedException {
while(hasString == false) { //we only want to put a string into the buffer if it is empty
wait();
}
this.string = string;
hasString = true;
notify();
}
/**
* passes on a string to the reader
* @throws InterruptedException
*/
public synchronized String get() throws InterruptedException {
while(hasString == true) { //we only want to pass on a string if the buffer is NOT empty
wait();
}
hasString = false;
notify();
return string;
}
代码现在可以工作(在@whaat 回答的帮助下),只需更改 Buffer-class 中的代码,同时保持 Writer 和 Reader 不变。我会在这里留下缓冲区的工作代码,以防其他人遇到和我一样的问题:)
/**
* gets a string from the writer
* @throws InterruptedException
*/
public synchronized void put(String string) throws InterruptedException {
while(hasString == true) { //we only want to put a string into the buffer if it is empty
wait();
}
this.string = string;
hasString = true;
notify();
}
/**
* passes on a string to the reader
* @throws InterruptedException
*/
public synchronized String get() throws InterruptedException {
while(hasString == false) { //we only want to pass on a string if the buffer is NOT empty
wait();
}
hasString = false;
notify();
return string;
}