0

I got the following problem:

I want to use the mediator pattern for an app.

I got a producer that creates values. I got a mediator that stores the values in a queue(which is private, so getters and setters exist) and notifices the consumer that there are new values in the queue. I got the consumer, that gets notified about a new value, gets it and does stuff with it...

I want all 3 classes to run on own threads. But I also want to be efficient.

If I understand it right, my mediator thread will be GCed when run() ends... so I would need to keep it alive by a loop, don't I? Like while(true), but this is not very efficient. Is there a better way? Or am I totally incorrect and the mediator wouldn't be GCed?

Thanks in advance

Ginbak
  • 105
  • 9

1 Answers1

0

You're right that once your mediator object's run() method returns, the thread will terminate. But that doesn't mean that the mediator will be GCed; if there is a live reference to your mediator object, it won't be. However, if the thread has exited, the mediator won't be particularly useful. A while(true) loop is one way to deal with this. A while(true) loop is not necessarily inefficient. It could easily work by calling wait() on some object until new stuff appears in the queue. The thread will be in a wait state and will not consume cpu resources.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • hey there. sounds great for the beginning. but what do you mean by "calling wait() on some object"? could you please give me an example? – Ginbak Oct 06 '14 at 00:52
  • @Ginbak - Take a look at [this thread](http://stackoverflow.com/questions/7597742/what-is-the-purpose-of-looper-and-how-to-use-it) which discusses how to use Android's `Looper` class to implement a message handling loop in a thread. It's not clear to me why the mediator needs to be a thread at all. It should just be a data structure that mediates communication between one thread (the producer) and another (the consumer), notifying the consumer when there's more work available, but not doing any work itself. – Ted Hopp Oct 06 '14 at 02:01
  • you are right. this is what I had. But in my design, the mediator was called by the consumer and was just a class with the queue in it. But as far as I understand it that leaves the queue blocked while the consumer thread does some other work which means, my queue was always empty and the producer waited to the consumer to finish and "release" the mediator. Or am I getting that wrong? :/ – Ginbak Oct 06 '14 at 08:43
  • @Ginbak - It's easy enough to design the queue so that it does not block the consumer when the queue is empty: provide an API query to test whether the queue is empty, or else return `null` or some other special value when it is. The consumer should only hold the queue until it has retrieved a value (or determined that no value is currently available). It should then release the queue (so the producer is free to add more items) and do whatever work it needs to do based on the result (and possibly some other work). – Ted Hopp Oct 06 '14 at 14:51
  • @Ginbak - I also meant to mention that you can design this either with the consumer polling the queue for values or using a wait/notify protocol where the consumer goes into a wait state when the queue is empty (by calling `wait()` on some synchronized shared object and is notified by the queue when new values arrive (by calling `notify()` or `notifyAll()` on the same shared object). – Ted Hopp Oct 06 '14 at 14:54
  • here is the problem I am having: the consumer and the mediator are running on one thread. the mediator got a `linkedBlockingQueue` and is observable while the consumer is observer. the producer is on another thread. I use methods to poll and push to queue. When the producer calls push, the value gets pushed to queue and then `setChanged`and `notify` are called. But it seems like then the consumer does what he wants and only when he finishes the mediator finishes the methodcall and only then returns to the producer and he can add another value. How can I fixe this? – Ginbak Oct 06 '14 at 20:13
  • @Ginbak - Don't use an observable protocol, where the mediator invokes a method in the consumer to carry out the work. Instead, use `notify()` to wake up the consumer and let the consumer (in its own separate thread) retrieve the value from the mediator and do the work. The mediator is locked only for the time it takes to retrieve the value, not for the entire duration of the work. – Ted Hopp Oct 07 '14 at 02:13