多线程代码以异步方式访问资源(例如:文件系统)。
为实现这一目标,我将使用条件变量。假设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()
会立即返回吗?
(我知道在使用锁读取时存在一些愚蠢,但写入文件也是一种选择。)
答案 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}}变得不稳定,因为它不同步。