Object creation vs. ThreadLocal retrieval

I

Ian Pilcher

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!
 
N

NOBODY

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;
}
}


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.
}
 
C

Chris Uppal

Ian said:
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?

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
 
N

NOBODY

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.
;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top