调度两个线程(ReadData
和WriteData
)时出现问题。看来我等不及通知。
这是我定义和调用的班级:
缓冲区:我用来读取/写入数据的缓冲区。我同步这堂课。
public class Buffer {
// Size of buffer we use to store data
public static final int SIZE = 10;
// Data of buffer.
private int[] values;
// Count of element in data.
private int count;
// Instance of buffer, for singleton pattern
private static Buffer instance = null;
// A signal show data in use (busy) or not
private static Object mutex = new Object();
// Constructor of buffer
private Buffer(){
values = new int[SIZE];
count = 0;
}
// Get instance of buffer.
public static Buffer getInstance(){
if(instance == null){
synchronized (mutex) {
if(instance == null) instance = new Buffer();
}
}
return instance;
}
public void addValue(int value){
synchronized (mutex) {
if(count >= SIZE) return;
values[count++] = value;
}
}
// Return current data and then reset buffer.
public int[] getValues(){
synchronized (mutex) {
if(count == 0) return null;
int[] values = new int[count];
System.arraycopy(this.values, 0, values, 0, count);
count = 0;
return values;
}
}
public int getCount(){
synchronized (mutex) {
return count;
}
}
}
ReadData:我用于将数据存储到缓冲区中的此类。
import java.util.Random;
public class ReadData implements Runnable {
Buffer buffer = Buffer.getInstance();
@Override
public synchronized void run() {
Random random = new Random();
while(true){
if(buffer.getCount() >= Buffer.SIZE){
try {
System.out.println("Read: is waiting. . .");
mState.readIsWaiting();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("Read: storing data");
buffer.addValue(random.nextInt(Buffer.SIZE) + 1);
}
}
}
public interface ReadState{
void readIsWaiting();
}
private ReadState mState;
public void setReadState(ReadState state){
mState = state;
}
public synchronized void makeNotify() {
notifyAll();
}
}
WriteData:我用来从缓冲区获取数据的此类
public class WriteData implements Runnable {
Buffer buffer = Buffer.getInstance();
@Override
public synchronized void run() {
while(true){
if(buffer.getCount() == 0){
try {
System.out.println("Write: is waiting. . .");
mState.writeIsWaiting();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
int[] getdata = buffer.getValues();
System.out.println("first data: " + getdata[0]);
}
}
}
public interface WriteState{
void writeIsWaiting();
}
private WriteState mState;
public void setWriteState(WriteState state){
mState = state;
}
public synchronized void makeNotify() {
notifyAll();
}
}
MyThread:我用来开始读/写的线程
package main;
import testing.ReadData;
import testing.WriteData;
public class MyThread implements ReadData.ReadState, WriteData.WriteState {
private ReadData read;
private WriteData write;
public void start(){
read = new ReadData();
write = new WriteData();
read.setReadState(this);
write.setWriteState(this);
new Thread(read).start();
new Thread(write).start();
}
@Override
public void writeIsWaiting() {
read.makeNotify();
}
@Override
public void readIsWaiting() {
write.makeNotify();
}
}
而已。有时它会起作用,很多时候它会停止并等待。
我该如何解决这个问题?谢谢
最佳答案
我认为您已经用WriteData颠倒了ReadData实现。在显示的代码中,如果缓冲区已满,ReadData线程将阻塞:
@Override
public synchronized void run() {
Random random = new Random();
while(true){
if(buffer.getCount() >= Buffer.SIZE){
try {
System.out.println("Read: is waiting. . .");
mState.readIsWaiting();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("Read: storing data");
buffer.addValue(random.nextInt(Buffer.SIZE) + 1);
}
}
}
您真正需要的是:
@Override
public synchronized void run() {
Random random = new Random();
while(true){
if(buffer.getCount() == 0){
try {
System.out.println("Read: is waiting. . .");
mState.readIsWaiting();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("Read: storing data");
buffer.addValue(random.nextInt(Buffer.SIZE) + 1);
}
}
}
同样,在WriteData实现中,如果缓冲区已满,则应阻塞。如果读者没有机会从缓冲区中取出元素,则会发生这种情况。这应该适用于WriteData代码:
@Override
public synchronized void run() {
while(true){
if(buffer.getCount() >= Buffer.SIZE){
try {
System.out.println("Write: is waiting. . .");
mState.writeIsWaiting();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
int[] getdata = buffer.getValues();
System.out.println("first data: " + getdata[0]);
}
}
}