1

How would you implement a Listener that is queuing events that are executed at the end of thread execution in multithreading environment? The desired behavior would be that each thread has its own queue for events so that they wouldn't mix up and be atomically executed.. So that if thread A calls listener.execute() then only "his" events get executed.

The only way I can think of is using ThreadLocal variable but if I consider the complications here I'd rather not use any.

Let say you have a Tree and you want to remove x nodes, then you don't want to execute refresh x times after each "refresh" event, but you better want to queue them and execute at the end...that spares x-1 refreshes :-)

Community
  • 1
  • 1
lisak
  • 21,611
  • 40
  • 152
  • 243
  • I don't really understand what you want to do. A listener listens to events. It doesn't queue events. And why can't you pass a different queue, or a different listener, to each thread? – JB Nizet Jul 03 '12 at 20:14
  • Some events are executed immediately and some Event types must be executed atomically at once (at the end) because that relate to each other in a way... Pass different listener to a thread ? – lisak Jul 03 '12 at 20:24
  • `for (int i = 0; i < 10; i++) { Runnable r = new MyRunnable(new MyListener()); new Thread(r).start(); }` – JB Nizet Jul 03 '12 at 20:26
  • Well those threads are "per http request" so I don't control them :-) – lisak Jul 03 '12 at 20:32
  • 1
    And when do you want to execute the queued events? At the end of the request? Why don't you store the events in a request attribute, and have the servlet or a filter execute the events at the end of the request handling? – JB Nizet Jul 03 '12 at 20:49
  • Sloin, what's your environment? Are you inside a Spring-configured application? Then it would be a breeze to set up an around-method advice that would make a `ThreadLocal` available and clear it automatically in the end, escaping any issues. It would also execute all the queued tasks. – Marko Topolnik Jul 03 '12 at 20:51
  • @JB Nizet, I execute them at the end of an atomic structural change (usually one per request) that consists of several smaller changes.. not at the end of request. It's behind the service layer, there are no requests anymore...which might be wrong, I could pass a per request context object down. – lisak Jul 03 '12 at 21:24
  • This sort of feels like [`ExecutionList`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/util/concurrent/ExecutionList.html). – Louis Wasserman Jul 03 '12 at 21:48
  • Well, like the otehr commetnsrs/poters, I'm not too sure what you want to achieve. If you want some 'OnCompletion' event to be called, it's common to use just one and pass sufficient parameters in so that the event can take the required action/s. Usually, it's just 'this' for whatever object was queued up, though you can load up a data member with a thread ID if you are particularly bothered about which thread ran it. – Martin James Jul 04 '12 at 02:35

2 Answers2

1

If you really want to avoid ThreadLocal, you could inverse the pattern and store a weak reference of the owner thread with every event in your (unique) queue.

This would also allow the redeploying to any other thread if the owner isn't available anymore.

But I'm a little unsure as I never saw the need for such a queue of events executed at "end of thread execution". Do you really have threads or are they really tasks or runnables ?

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
0

If each thread is going to have its OWN queue at the END of its execution, aren't all your Queues going to be just 1-MEMBER queues?

srini.venigalla
  • 5,137
  • 1
  • 18
  • 29