Java 如何在Rox NIO教程中消除竞争条件

Java 如何在Rox NIO教程中消除竞争条件,java,nio,race-condition,Java,Nio,Race Condition,我一直在使用教程介绍使用socket IO的简单文件传输客户端/服务器。我更改了响应处理程序,将多个读取作为一个文件的一部分,因为我将处理可能高达500 MB的大型文件。本教程没有考虑大型服务器的响应,所以我有点挣扎,我创建了一个竞争条件 以下是响应处理程序代码: public class RspHandler { private byte[] rsp = null; public synchronized boolean handleResponse(byte[] rsp) { th

我一直在使用教程介绍使用socket IO的简单文件传输客户端/服务器。我更改了响应处理程序,将多个读取作为一个文件的一部分,因为我将处理可能高达500 MB的大型文件。本教程没有考虑大型服务器的响应,所以我有点挣扎,我创建了一个竞争条件

以下是响应处理程序代码:

public class RspHandler {

private byte[] rsp = null;
public synchronized boolean handleResponse(byte[] rsp) {
    this.rsp = rsp;
    this.notify();
    return true;
}

public synchronized void waitForResponse() {
    while(this.rsp == null) {
        try {
            this.wait();
        } catch (InterruptedException e) {
        }
    }
    System.out.println("Received Response : " + new String(this.rsp));
}

public synchronized void waitForFile(String filename) throws IOException {
    String filepath = "C:\\a\\received\\" + filename;
    FileOutputStream fos = new FileOutputStream(filepath);
    while(waitForFileChunk(fos) != -1){}
    fos.close();
}

private synchronized int waitForFileChunk(FileOutputStream fos) throws IOException
{
    while(this.rsp == null) {
        try {
            this.wait();
        } catch (InterruptedException e) {
        }
    }
    fos.write(this.rsp);
    int length = this.rsp.length;
    this.rsp = null;
    if(length < NioClient.READ_SIZE)//Probably a bad way to find the end of the file
    {
        return -1;
    }
    else
    {
        return length;
    }

}
}
公共类RspHandler{
专用字节[]rsp=null;
公共同步布尔句柄响应(字节[]rsp){
这是rsp=rsp;
this.notify();
返回true;
}
公共同步的void waitForResponse(){
while(this.rsp==null){
试一试{
这个。等等();
}捕捉(中断异常e){
}
}
System.out.println(“收到的响应:+新字符串(this.rsp));
}
公共同步的void waitForFile(字符串文件名)引发IOException{
String filepath=“C:\\a\\received\\”+文件名;
FileOutputStream fos=新的FileOutputStream(filepath);
while(waitForFileChunk(fos)!=-1{}
fos.close();
}
私有同步int waitForFileChunk(FileOutputStream fos)引发IOException
{
while(this.rsp==null){
试一试{
这个。等等();
}捕捉(中断异常e){
}
}
fos.write(本rsp);
int length=this.rsp.length;
this.rsp=null;
if(length
程序的主线程在主线程上创建一个RspHandler,并将其传递给在单独线程上创建的客户机。主线程告诉客户端请求一个文件,然后告诉RspHandler侦听响应。当客户端从服务器读取数据时(它现在以大约1KB的数据块读取),它调用
handleResponse(byte[]rsp)
方法,填充rsp字节数组


从本质上说,我并没有像它来的那么快地将接收到的数据写入文件。我对线程有点陌生,所以我不确定如何摆脱这种竞争条件。有什么提示吗?

这是经典的消费者/生产者。处理此问题最直接/最简单的方法是使用BlockingQueue。生产者调用
put()
,消费者调用
take()

注意,使用BlockingQueue通常会导致“如何完成”问题。最好的方法是使用“毒药丸”方法,生产商在队列上粘贴一个“特殊”值,向消费者发出不再有数据的信号