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

标签 java nio race-condition

我一直在使用 this使用套接字 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,并将其传递给在单独线程上创建的客户端。主线程告诉客户端请求文件,然后告诉 RspHandler 监听响应。当客户端从服务器读取时(它现在读取大约 1KB 的 block ),它调用 handleResponse(byte[] rsp) 方法,填充 rsp 字节数组。

本质上,我并没有把接收到的数据尽快写入文件。我对线程有点陌生,所以我不确定该怎么做才能摆脱这种竞争状况。有什么提示吗?

最佳答案

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

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

关于java - 如何在 Rox NIO 教程中消除竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8807551/

相关文章:

scala - 在Scala中处理文件时出现java.nio.BufferUnderflowException

c# - c#静态构造函数中的竞争条件

javascript - 在 Cypress 的片状测试中寻找 cy.wait() 的替代品

java - Spring Data JPA - 注入(inject)失败 - BeanCreationException : Could not autowire field

java - JRE 到期日

Java - 在数据接收时向另一个线程触发事件

C使用管道传输数据以使用共享内存写入文件

java - 自定义 JFreeChart 标题字体太小

java - 处理循环依赖

java - 使用 java nio 将字符串写入文件的最佳方法