生产者/消费者应用程序的设计 [英] design of a Producer/Consumer app

查看:155
本文介绍了生产者/消费者应用程序的设计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个生产者应用程序,该应用程序生成一个索引(将其存储在某些内存树数据结构中).消费者应用程序将使用索引来搜索部分匹配项.

I have a producer app that generates an index (stores it in some in-memory tree data structure). And a consumer app will use the index to search for partial matches.

在生产者索引数据时,我不希望消费者UI不得不阻塞(例如,通过某些进度条).基本上,如果用户希望使用部分索引,它只会这样做.在这种情况下,生产者可能必须停止索引一段时间,直到用户转到另一个屏幕为止.

I don't want the consumer UI to have to block (e.g. via some progress bar) while the producer is indexing the data. Basically if the user wishes to use the partial index, it will just do so. In this case, the producer will potentially have to stop indexing for a while until the user goes away to another screen.

大致上,我知道我将需要等待/通知协议来实现此目的.我的问题:在生产者线程进行业务时,是否可以使用等待/通知来中断生产者线程?我需要什么java.util.concurrent原语来实现这一目标?

Roughly, I know I will need the wait/notify protocol to achieve this. My question: is it possible to interrupt the producer thread using wait/notify while it is doing its business ? What java.util.concurrent primitives do I need to achieve this ?

推荐答案

在生产者线程中,您可能具有某种主循环.这可能是打断您的制作人的最佳位置.建议您不要使用java 5中引入的java同步对象,而不要使用wait()和notify().

In your producer thread, you are likely to have some kind of main loop. This is probably the best place to interrupt your producer. Instead of using wait() and notify() I suggest you use the java synchronization objects introduced in java 5.

您可能会做类似的事情

class Indexer {

   Lock lock = new ReentrantLock();    

    public void index(){
        while(somecondition){
            this.lock.lock();
            try{
                // perform one indexing step
            }finally{
                lock.unlock();
            }
        }
    }

    public Item lookup(){
        this.lock.lock();
        try{
            // perform your lookup
        }finally{
            lock.unlock();
        }
    }
}

您需要确保每次索引器释放锁时,索引都处于一致的合法状态.在这种情况下,当索引器释放该锁时,它将为新的或等待的lookup()操作留出机会来获取该锁,完成并释放该锁,此时,索引器可以继续进行下一步.如果当前没有任何lookup()等待,那么索引器将自动获取该锁本身并继续执行下一个操作.

You need to make sure that each time the indexer releases the lock, your index is in a consistent, legal state. In this scenario, when the indexer releases the lock, it leaves a chance for a new or waiting lookup() operation to take the lock, complete and release the lock, at which point your indexer can proceed to its next step. If no lookup() is currently waiting, then your indexer just reaquires the lock itself and goes on with its next operation.

如果您认为可能有多个线程试图同时执行查找,则可能需要查看ReadWriteLock接口和ReentrantReadWriteLock实现.

If you think you might have more that one thread trying to do the lookup at the same time, you might want to have a look at the ReadWriteLock interface and ReentrantReadWriteLock implementation.

当然,此解决方案是执行此操作的简单方法.它将阻塞没有锁的任何一个线程.您可能想检查一下是否可以直接在数据结构上直接进行同步,但这可能会很棘手,因为在建立索引时,倾向于使用某种平衡树或B-Tree或其他类似的方法,而节点插入操作却并非易事.

Of course this solution is the simple way to do it. It will block either one of the threads that doesn't have the lock. You may want to check if you can just synchronize on your data structure directly, but that might prove tricky since building indexes tends to use some sort of balanced tree or B-Tree or whatnot where node insertion is far from being trivial.

我建议您首先尝试这种简单的方法,然后看看它的行为方式是否适合您.如果不是这样,您可以尝试将索引编制步骤分解为较小的步骤,也可以尝试仅对数据结构的某些部分进行同步.

I suggest you first try that simple approach, then see if the way it behaves suits you. If it doesn't, you may either try breaking up the the indexing steps into smaller steps, or try synchronizing on only parts of your data structure.

不必太担心锁定的性能,在Java无竞争的锁定中(当只有一个线程试图获取该锁定时)很便宜.只要您对大多数锁定都不满意,就不必担心锁定性能.

Don't worry too much about the performance of locking, in java uncontended locking (when only one thread is trying to take the lock) is cheap. As long as most of your locking is uncontented, locking performance is nothing to be concerned about.

这篇关于生产者/消费者应用程序的设计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆