I have a method which searches a singly linked list for an object. It
needs to return references to both the object and the preceding object
in the list. I have created a very simple inner class to encapsulate
this information:
private final class MemberReference
{
final Member referent;
final Member previous;
MemberReference(Member referent, Member previous)
{
this.referent = referent;
this.previous = previous;
}
}
An instance of this class will be required for just about every access
the the class, including reads, which could cause a lot of these objects
to be created and then discarded.
I'd like to avoid this if possible, but the class does need to support
reading by multiple threads, so I wouldn't want to use a single
instance (or a couple of class fields). I'm thinking of using a
ThreadLocal, but I can't help wondering if retrieving the thread-local
value might not be more expensive than creating a new object.
Anyone have any experience/thoughts?
Thanks!

Signature
========================================================================
Ian Pilcher i.pilcher@comcast.net
========================================================================
NOBODY - 28 Oct 2005 01:18 GMT
> I have a method which searches a singly linked list for an object. It
> needs to return references to both the object and the preceding object
[quoted text clipped - 12 lines]
> }
> }
Note 1: I will assume that this is not clashing with interface
java.lang.reflect.Member.
Note 2: I will suggest you make all your innerclasses static, unless they
actually need their enclosing class which is easy to find with a good
IDE. (private static final class MemberReference)
I'm not sure why you cannot simply have 2 local variable in the loop that
traverses the linked list.
Object prev = null, current = null;
Iterator it=list.iterator();
for(Iterator it=list.iterator(); it.hasNext();) {
prev = current;
current = it.next();
//do stuff, possibly break.
}
You must be going through some 3rd party code that runs your code (some
visitor pattern) for you to need such a hack to return 'prev' and
'current'.
The answer: threadlocal lookup is an order(1) hashmap lookup. That is
pretty fast. I recommend it, even if bad mouths will tell you that with
modern jvm 'new' and garbage collection is faster, is it still CPU that
you don't use when you use a thread local (you use it differently but at
least you use it on every thread, not just a bunch of GC threads).
The 2 other ways around: a static variable (since you are not
multithreaded), but that is always ugly. The other way is only if you
defined your own thread class: you can put a public field/method in the
thread subclass instance that any code can access given a cast of current
thread:
public class MyThread extends Thread {
Object prev;
Object current;
public void setCurrent(Object x) {
prev = current;
current = x;
}
public void clear() {
prev = current = null;
}
}
MyThread t = (MyThread)Thread.currentThread();
t.clear();
Iterator it=list.iterator();
for(Iterator it=list.iterator(); it.hasNext();) {
t.setCurrent(it.next());
//do stuff, possibly break.
}
> An instance of this class will be required for just about every access
> the the class, including reads, which could cause a lot of these
[quoted text clipped - 9 lines]
>
> Thanks!
Chris Uppal - 28 Oct 2005 11:20 GMT
> I'd like to avoid this if possible, but the class does need to support
> reading by multiple threads, so I wouldn't want to use a single
[quoted text clipped - 3 lines]
>
> Anyone have any experience/thoughts?
I think that unless you have an actual /measured/ performance problem, then you
are overcomplicating things by even considering this issue.
OTOH, if you /do/ have a performance problem, why not just establish the
convention of always returning the previous item, (since the next one can be
trivially found from that) ? Obviously you'd need some added logic to
distinguish the case where the discovered element was the first one, and so
there was no previous element, but that could be handled easily enough -- for
instance by having a dummy object at the head of each list.
-- chris
NOBODY - 29 Oct 2005 13:59 GMT
>> I'd like to avoid this if possible, but the class does need to
>> support reading by multiple threads, so I wouldn't want to use a
[quoted text clipped - 7 lines]
> I think that unless you have an actual /measured/ performance problem,
> then you are overcomplicating things by even considering this issue.
I gave 3 solutions spread over the spectrum of complexity.
Of course, like most people who always want the last word, you had to focus
on the tough one just to fill your quota of criticism today. At least you
gave a smart 4th solution and prooved you can also be constructive.
;-)
> OTOH, if you /do/ have a performance problem, why not just establish
> the convention of always returning the previous item, (since the next
[quoted text clipped - 5 lines]
>
> -- chris