1

一段多线程代码异步访问资源(例如:文件系统)。

为此,我将使用条件变量。假设FileSystem是这样的接口:

class FileSystem {
    // sends a read request to the fileSystem
    read(String fileName) {
        // ...
        // upon completion, execute a callback
        callback(returnCode, buffer);
    }
}

我现在有一个应用程序访问FileSystem. readFile()假设我可以通过一个方法发出多次读取。该操作应将数据写入传递给它的字节缓冲区。

// constructor
public Test() {
    FileSystem disk = ...
    boolean readReady = ...
    Lock lock = ...

    Condition responseReady = lock.newCondition();
}

// the read file method in quesiton
public void readFile(String file) {
    try {
        lock.lock(); // lets imagine this operation needs a lock

        // this operation may take a while to complete; 
        // but the method should return immediately
        disk.read(file); 

        while (!readReady) { // <<< THIS
            responseReady.awaitUninterruptibly();
        }
    } 
    finally {
        lock.unlock();
    }
}

public void callback(int returnCode, byte[] buffer) {
    // other code snipped...

    readReady = true;  // <<< AND THIS
    responseReady.signal();
}

这是使用条件变量的正确方法吗?会readFile()马上回来吗?

(我知道使用锁进行读取有些愚蠢,但写入文件也是一种选择。)

4

1 回答 1

1

您的问题有很多遗漏(即没有具体提及线程),但无论如何我都会尝试回答。

锁和条件变量都没有给你后台功能——它们只是用于一个线程等待来自其他线程的信号。虽然你没有提到它,但该disk.read(file)方法可以产生一个线程来执行 IO,然后立即返回,但调用者无论如何都会坐在readReady循环中,这似乎毫无意义。如果调用者必须等待,那么它可以自己执行 IO。

更好的模式可能是使用 Java 5 Executors 服务之类的东西:

 ExecutorService pool = Executors.newFixedThreadPool(int numThreads);

然后,您可以调用pool.submit(Callable)which 将提交要在另一个线程中在后台执行的作业(当池下一个可用时)。提交返回Future调用者可以用来调查后台任务是否已完成。它也可以返回一个结果对象。并发类为您处理锁定和条件信号/等待逻辑。

希望这可以帮助。

ps 另外,您应该readReady设置为 volatile,因为它不同步。

于 2010-11-17T03:06:44.197 回答