多线程代码和条件变量的使用

发布于 2024-10-02 11:10:51 字数 1288 浏览 1 评论 0原文

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

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

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

A multi-threaded piece of code accesses a resource (eg: a filesystem) asynchronously.

To achieve this, I'll use condition variables. Suppose the FileSystem is an interface like:

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

I have now an application accessing the FileSystem. Suppose I can issue multiple reads through a readFile() method.
The operation should write data to the byte buffer passed to it.

// 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();
}

Is this the correct way to use condition variables? Will readFile() return immediately?

(I know there is some sillyness in using locks for reads, but writing to a file is also an option.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听你说爱我 2024-10-09 11:10:51

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

锁和条件变量都不提供后台功能——它们只是用于线程等待来自其他线程的信号。尽管您没有提及,disk.read(file) 方法可以生成一个线程来执行 IO,然后立即返回,但调用者将处于 readReady code> 无论如何循环这似乎毫无意义。如果调用者必须等待,那么它可以自行执行 IO。

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

 ExecutorService pool = Executors.newFixedThreadPool(int numThreads);

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

希望这有帮助。

ps 此外,您应该使 readReady 具有易失性,因为它不同步。

There's a lot missing from your question (i.e. no specific mention of Threads) but I will try to answer anyway.

Neither the lock nor the conditional variables give you background capabilities -- they just are used for a thread to wait for signals from other threads. Although you don't mention it, the disk.read(file) method could spawn a thread to do the IO and then return immediately but the caller is going to sit in the readReady loop anyway which seems pointless. If the caller has to wait then it could perform the IO itself.

A better pattern could be to use something like the Java 5 Executors service:

 ExecutorService pool = Executors.newFixedThreadPool(int numThreads);

You can then call pool.submit(Callable) which will submit the job to be performed in the background in another thread (when the pool next has one available). Submit returns a Future which the caller can use to investigate if the background task has finished. It can return a result object as well. The concurrent classes take care of the locking and conditional signal/wait logic for you.

Hope this helps.

p.s. Also, you should make readReady be volatile since it is not synchronized.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文