多线程代码和条件变量用法

时间:2010-11-17 01:59:36

标签: java multithreading asynchronous monitor condition-variable

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

为实现这一目标,我将使用条件变量。假设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()会立即返回吗?

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

1 个答案:

答案 0 :(得分:1)

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

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

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

 ExecutorService pool = Executors.newFixedThreadPool(int numThreads);

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

希望这有帮助。

P.S。此外,您应该使{{1}}变得不稳定,因为它不同步。