Hard Core Java: ThreadLocal

Discussions

News: Hard Core Java: ThreadLocal

  1. Hard Core Java: ThreadLocal (37 messages)

    Bob Lee (a.k.a CrazyBob) has started a series on hardcore Java. The first installment offers an example loaded view on how one can use a thread local variable to carry values throughout the execution path of your application. The article covers a lot of ground as it addresses the basics of how one uses this feature to reentrance as well as some of the gotchas that one can run into along the way.
    If we don't want our ThreadLocal instance to prevent the garbage collection of the Context class, we should use an Object[] instead of a Context[].
    Included are numerous snippets of code that very tidally illustrate each of the points discussed. The final bit of advice offered is that debugging code using thread locals can be tricky and it maybe better to use a pattern such as dependency injection. This entry is a must read if you are interested in learning more about threading and hardcore Java. Message was edited by: kirk@javaperformancetuning.com

    Threaded Messages (37)

  2. Re: Hard Core Java: ThreadLocal[ Go to top ]

    I think threadlocal is very handy for passing information without using arguments, keeping your code clean. I use it for transaction management (who doesn't?) and also right management.
  3. The author does mention, "remember to explicitly clear the value in a finally block to prevent memory leaks". Don't forget this, especially if you are using thread pools. I once encountered a nasty memory leak that was very difficult to track down. It turns out we weren't cleaning up our thread local space on the threads, so every time our thread pool reclaimed threads, the threads would remain resident in memory. IIRC, Apache Axis contained the offending code. We submitted a patch to Apache, but it was never taken. I believe the bug is still there, although it takes a rather obtuse bit of code to expose the bug. Another place where this bites people? Hot-deploy app servers. When I last looked (maybe 18 months ago?), Jakarta Commons Logging where you pass ".class" to the constructor of the logger (a fairly common usage pattern) causes the class to be pushed on to thread local space. When you hot deploy a war file that replaces the old war file, the classes never get reclaimed and unloaded, resulting in another memory leak. Of course, hot deploy shouldn't be used in production. But when you are trying to debug a memory leak, this one can really bite you if you aren't aware of it.
  4. Another place where this bites people? Hot-deploy app servers. When I last looked (maybe 18 months ago?), Jakarta Commons Logging where you pass ".class" to the constructor of the logger (a fairly common usage pattern) causes the class to be pushed on to thread local space. When you hot deploy a war file that replaces the old war file, the classes never get reclaimed and unloaded, resulting in another memory leak. Of course, hot deploy shouldn't be used in production. But when you are trying to debug a memory leak, this one can really bite you if you aren't aware of it.
    This is why I always use a LogFactory.release(Thread.currentThread().getContextClassLoader()); (among other things) in a ServletContextListener in all my applications. It catches the case where the application forgot to cleanup. An alternative is to use MessAdmin, which will give you this behaviour (and lots of others!) for free.
  5. Tapestry and Thread Locals[ Go to top ]

    Tapestry makes quite a bit of use of thread locals to store per-thread/per-request information (the servlet or portlet API objects, and objects derived from them, primarily). However, Tapestry uses a feature built into the HiveMind IoC container to manage thread local information: the "threaded" service lifecycle model. If you declare a service as "threaded" in HiveMind, then a seperate copy is kept for each thread. The same proxy object can be shared across threads, invokation on a proxy in any thread will be delegated to a real implementation reserved for that thread. So you get to code and test as if the service was global, as if there was only one thread. At runtime, it Just Works, even in a heavily threaded environment. Better yet, all the work of dealing with a ThreadLocal is buried deeply inside HiveMind, where it has been tested to death. Tapestry's main request path, inside the servlet, includes a call into HiveMind to "clean up threading" ... discard thread locals. This is another example of "seperation of concerns" and another good reason to use a container for your code.
  6. Thread Resue[ Go to top ]

    One must be aware (as pointed out in the article) of context cleanup, especialy in the case of Applications Servers that reuse threads (and it's local variables) between diferent invocations, clients and sometimes layers. Where to put a process end-point for cleaning ? Also on remote calls (i.e RMI) the calling method and receiving service usually are not on the same Thread (hense not on the same thread variable context)! Rudolf
  7. Keep reuse in mind[ Go to top ]

    I once had to refactor a system which made heavy use of Threadlocals. The pain was, that you can't identify the required arguments to a method just by looking on the parameters any more, because somewhere down the stack a Threadlocal is accessed by a static method. This makes reusing methods really hard, because the dependency on the Threadlocal is not explicitely expressed and most of times is not mentioned in comments up the stack either. It's like always: use is wisely and in rare cases.
  8. I would agree with your comments here, Mika, and it makes me wonder if ThreadLocal's are really just global variables in different clothing. They certainly seem to be used that way in the system you describe, as well as in some earlier examples in this thread. Seems to me that using ThreadLocal runs the risk of all the same evil things that happen with globals - proliferation of accesses to it from all over the code (hell, difficulty of even *finding* all the accesses to it), difficulty of refactoring it away, etc. Granted, with ThreadLocal the situation is slightly better than with globals, because accesses are within the same thread, but not much. You could have hundreds and hundreds of objects in your system that all operate in the same thread, and are all accessing a particular ThreadLocal from hundreds of different directions. Looks to me like this is so open for abuse, that I'd be leery about using it. Am I right, or am I'm missing something here? DR
  9. Looks to me like this is so open for abuse, that I'd be leery about using it.

    Am I right, or am I'm missing something here?

    DR
    You're not missing anything. ThreadLocals are evil. Unfortunately, they're a necessary evil in a small number of cases. I agree with Howard that you should generally let frameworks / containers deal with this for you if you can, since those codebases will be tested out on many different apps in different environments. If you ever find yourself setting up a ThreadLocal, go back and make sure there's not another way to do it. Can you just pass it as a method parameter? If you still think you need a ThreadLocal, repeat the above ;-)
  10. Looks to me like this is so open for abuse, that I'd be leery about using it.

    Am I right, or am I'm missing something here?

    DR


    You're not missing anything. ThreadLocals are evil. Unfortunately, they're a necessary evil in a small number of cases. I agree with Howard that you should generally let frameworks / containers deal with this for you if you can, since those codebases will be tested out on many different apps in different environments. If you ever find yourself setting up a ThreadLocal, go back and make sure there's not another way to do it. Can you just pass it as a method parameter? If you still think you need a ThreadLocal, repeat the above ;-)
    I think that ThreadLocal data should be contextual information of method invocation and, so, cannot be part of a method signature. Typical use is for transactional and security context. Any abuse can be source of evil and ThreadLocal obeys to this general law. But even not abusing of something you can rapidly get crazy: never access directly ThreadLocal methods. Just as an example, use some sort of Transaction txn = TransactionContext.getCurrent() rather than spread the ThreadLocal existence knowledge around. But this is a general engineering/encapsulation matter. Guido.
  11. I agree completely. ThreadLocal is generally only appropriate for highly optimized multithreaded applications, such as app servers. It allows shared data access (within a single-thread of execution) without synchronizion. The potential performance gains are very small with newer JVMs, as the penalty for uncontested locks has been virtually eliminated. Also, ThreadLocal itself incurs a performance hit, although that too has been reduced. In short, stay away from ThreadLocal unless you have a really, really good reason for using it.
  12. I would agree with your comments here, Mika, and it makes me wonder if ThreadLocal's are really just global variables in different clothing. They certainly seem to be used that way in the system you describe, as well as in some earlier examples in this thread.

    Seems to me that using ThreadLocal runs the risk of all the same evil things that happen with globals - proliferation of accesses to it from all over the code (hell, difficulty of even *finding* all the accesses to it), difficulty of refactoring it away, etc.

    Granted, with ThreadLocal the situation is slightly better than with globals, because accesses are within the same thread, but not much. You could have hundreds and hundreds of objects in your system that all operate in the same thread, and are all accessing a particular ThreadLocal from hundreds of different directions.

    Looks to me like this is so open for abuse, that I'd be leery about using it.

    Am I right, or am I'm missing something here?

    DR
    I was going to post something about how the class should be called 'ThreadGlobal' but realize that the ThreadLocal's scope is defined just like any other Object. If it's a private member, it can't be accessed from anywhere, only in that class. The other thing is that you can get the effect or a ThreadLocal by creating a Map of threads to Objects and calling Thread.currentThread(). The only time I've needed to do something like this was dealing with some old code that has thousands of calls to System.out and I needed write each thread's log to separate files without a lot of time to change all the code.
  13. ThreadLocal is the only way to apply a regular programming technique in a multi-user container: parameters passing via global variables. "Parameters passing via global variables" is not preferred way of parameters passing, but sometimes is the only appropriate. Environment variables in UNIX and Windows are a common example of "parameters passing via global variables". There could be better ways to enable this technique, but ThreadLocals are the only we have. So, if you don't use ThreadLocals, then you can't program an important technique. Follow the principle: Don't use a framework just because you can't program. Nebojsa
  14. ThreadGlobal[ Go to top ]

    There's nothing inherently "global" about ThreadLocal (though it can be [ab]used as such). In fact, you can have a private ThreadLocal instance variable which will have a smaller scope than a normal private instance variable; that's far from global.
  15. Re: ThreadGlobal[ Go to top ]

    There's nothing inherently "global" about ThreadLocal (though it can be [ab]used as such). In fact, you can have a private ThreadLocal instance variable which will have a smaller scope than a normal private instance variable; that's far from global.
    I can agree that there's nothing inherently "global" about ThreadLocal, but there is something "global" in most real life examples of ThreadLocal. ThreadLocals are the way to make a "thread static" field. "global" translated to Java means "public static", but focus is on "static", not on "public": private static field is usualy accessible throught a static method and acts as global value. Even if a field isn't static, but there is the only one instance of the object containing that field, a field can act as a global value. Most ThredLocal objects in real life act as global values, and make them "thread globals". We can probably agree that "thread globals" are a possible usage of the ThredLocal feature. But in my experience, it is also the most important usage. Nebojsa
  16. Re: ThreadGlobal[ Go to top ]

    We can probably agree that "thread globals" are a possible usage of the ThredLocal feature. But in my experience, it is also the most important usage.

    Nebojsa
    I find this to be more confusing than it is helpful. Values added to a ThreadLocal are "local to a given thread" and this scope is quite different than global, protected, package protected, and private -- all these scopes do not prevent multiple threads from accessing data, but thread local does.
    There's nothing inherently "global" about ThreadLocal (though it can be [ab]used as such). In fact, you can have a private ThreadLocal instance variable which will have a smaller scope than a normal private instance variable; that's far from global.
    Here's another reason (Message #214250) to not name this class ThreadGlobal: IMO seeing as there's nothing in Java that is truly global, naming something ThreadGlobal would IMO be a bad engineering decision.
  17. Maybe a reading of this: http://www.cs.wustl.edu/~schmidt/PDF/TSS-pattern.pdf could help. In the good old GoF style: motivation, applicability, known-use etc. Guido.
  18. Re: ThreadGlobal[ Go to top ]

    all these scopes do not prevent multiple threads from accessing data, but thread local does.
    True but a member variable cannot be accessed by a thread if that thread doesn't 'see' the Object. In this way we can prevent mulitple threads from accessing a value. This is much preferable to using ThreadLocals. In the article, for example, one use given is to pass a value from method to method without passing it through the arguments. I would argue that a much better approach would be to restructure the methods as members of a class and the same value can be stored in a member variable. This is much easier to understand, maintain, and reuse. Using ThreadLocals to achieve this effect is more of a sloppy hack than an advanced technique, IMO. There are definitely legitimate uses of ThreadLocal but I don't realy consider that one of them.
  19. Re: ThreadGlobal[ Go to top ]

    Using ThreadLocals to achieve this effect is more of a sloppy hack than an advanced technique, IMO. There are definitely legitimate uses of ThreadLocal but I don't realy consider that one of them.
    I guess it all depends upon your point of view. ThreadLocals are the typical means of passing transactions and security contexts around in containers through to clients. At the most basic level, this is doing exactly what you said was a hack: using ThreadLocals to avoid having to explicitly pass around parameters to other functions. I see it as something greater than that though: a general separation of concerns. I use ThreadLocals in the internals of a logging API so that clients can log messages like: log( "my message", throwable ) instead of: log( "my message", throwable, hostname, sessionId, threadId, transactionId, user, Foo.class, "Foo.someMethod( String, int )", "line 435" ); Again, at the most basic level, it's about not having to pass parameters explicitly. At a conceptual level, it's about separation of concerns.
  20. Re: ThreadGlobal[ Go to top ]

    Using ThreadLocals to achieve this effect is more of a sloppy hack than an advanced technique, IMO. There are definitely legitimate uses of ThreadLocal but I don't realy consider that one of them.
    I guess it all depends upon your point of view. ThreadLocals are the typical means of passing transactions and security contexts around in containers through to clients. At the most basic level, this is doing exactly what you said was a hack: using ThreadLocals to avoid having to explicitly pass around parameters to other functions. I see it as something greater than that though: a general separation of concerns.
    While I have no argument with what you are saying here, I don't think you are addressing my point exactly. ThreadLocals are a perfectly good way to associate data with a thread when it is not feasible to customize the threads with Runnable Objects. But associating data with a thread is not a great way to pass around parameters. Mainly because it is a procedural approach. Not to say that procedural approaches are always bad but they tend to be less than optimal in Java designs. It occured to me why ThreadLocal seems global-esque. It has the same quality that amkes globals so unworkable in practice. Using them required a blind hand-off. The caller has to have faith (in many cases) that the previous something-or-other put the right value into the ThreadLocal before it is needed. Sometimes there are too many parameters to pass around from one method to another. Instead of using a thread local, you can often use what I call a "object as method" pattern where the parameters become private (preferrably final) members of an Object with local scope.
    I use ThreadLocals in the internals of a logging API so that clients can log messages like:...
    That's not really the same situation. You are associating data with a thread so that when a method is called later, you can do something useful based on which thread is making the call. That's not the same thing putting things in a ThreadLocal as if you are handing-off loot via a bus-station locker like a drug-dealer.
  21. Re: ThreadGlobal[ Go to top ]

    True but a member variable cannot be accessed by a thread if that thread doesn't 'see' the Object. In this way we can prevent mulitple threads from accessing a value. This is much preferable to using ThreadLocals.
    I'm not going to disagree with this, however I will say that my limited understanding of application server internals is that they tend to associate one user with one thread and session data remains associated with that user's thread. In this scenario, using ThreadLocal would make sense.
  22. Re: ThreadGlobal[ Go to top ]

    True but a member variable cannot be accessed by a thread if that thread doesn't 'see' the Object. In this way we can prevent mulitple threads from accessing a value. This is much preferable to using ThreadLocals.


    I'm not going to disagree with this, however I will say that my limited understanding of application server internals is that they tend to associate one user with one thread and session data remains associated with that user's thread. In this scenario, using ThreadLocal would make sense.
    There are other ways to do this, however. You can create a custom Runnable class that all the threads use which contains the data. Using ThreadLocal would only make sense if you can't control what threads are being started or you did this as an after-thought. I guess I point here is that sometimes developers (including myself) can become so enamored with things like this that we forget to consider more straight-forward approaches. If you look at how ThreadLocal works, it's really not all that sexy anyway. Each Thread has a map of it's locals -> values and when you call get, it just usses Thread.currentThread() to get the map and calls map.get(this).
  23. Re: ThreadGlobal[ Go to top ]

    Using ThreadLocal would only make sense if you can't control what threads are being started [...]
    Which is the case whenever you code something that runs in an application server. A neat example of a "good" use of ThreadLocal is in JSF and FacesContext.getInstance(). Compare this to many other frameworks which forces framework users to pass HttpRequest et al around, polluting method signatures all over the place, because somewhere deep inside there might be some bloody utility method that needs. Anyhow, it doesnt make sense to mandate that anyone who needs thread local storage must also "own" the definition of all threads that the code might execute in.
  24. Re: ThreadGlobal[ Go to top ]

    Using ThreadLocal would only make sense if you can't control what threads are being started [...]


    Which is the case whenever you code something that runs in an application server.

    Perhaps that's what people were referring to but I took them to mean the actual application server's code instead. I would think it's dangerous to assume that you know that a single thread will execute all the steps of a given process that you deploy on an app server. You really have no business assuming anything about that. If your need is indeed thread specific then it makes sense to use ThreadLocals. If you are just passing around data in a process, it's very questionable to use an assumption about how the app server manages it's threads to pass data around. Of course if the specs say it must use a single thread you are probably pretty safe but most people will not spend the time required to verify that before using a technique like this.
    A neat example of a "good" use of ThreadLocal is in JSF and FacesContext.getInstance(). Compare this to many other frameworks which forces framework users to pass HttpRequest et al around, polluting method signatures all over the place, because somewhere deep inside there might be some bloody utility method that needs.

    I believe that is only safe because the spec says it will be the same thread. But again, you aren't suggesting that there is no other solution that could be developed that wouldn't require Thread based storage or paramters, are you? It seems to me that this is a work-around for a deficiency in the Servlet spec, if I understand you. Again, I've never suggested that ThreadLocals are not useful. I'm saying that they are more of a last resort than a good starting point.
    Anyhow, it doesnt make sense to mandate that anyone who needs thread local storage must also "own" the definition of all threads that the code might execute in.
    Did someone suggest that should be mandated?
  25. ThreadLocals internal structure[ Go to top ]

    Can someone explain me why ThreadLocals implements is own map? Why did they decide not to use HashTable and implements a rehash based hashtable? It really impacts the performace as I found out. Guy
  26. Re: ThreadLocals internal structure[ Go to top ]

    Can someone explain me why ThreadLocals implements is own map?

    Why did they decide not to use HashTable and implements a rehash based hashtable?
    It really impacts the performace as I found out.

    Guy
    ThreadLocal should perform much faster in multi-threaded situations than if you used a shared Hashtable.
  27. Re: Hard Core Java: ThreadLocal[ Go to top ]

    ... in a recent discussion that I've had about ThreadLocal's someone said that it breaks OOP principles. ... well that's debatable but still so what? OOP does not provide allthe times the most ellegant and efficient solutions. This is one of the reason why AOP was so widely adopted by the community. Getting back to ThreadLocal's, someone from the core team from my company had serious leaks and he just took out all the ThreadLocal's just because of this. The problem was that in fact the code was not doing any clean-up. I guess it's so easy to blame TreadLocal's when in fact programmers are making them un-effective. IMHO ThreadLocals/InheritableThreadLocals are making context propagation among application layer so much cleaner and ellegant.
  28. ... in a recent discussion that I've had about ThreadLocal's someone said that it breaks OOP principles. ... well that's debatable but still so what? OOP does not provide allthe times the most ellegant and efficient solutions. This is one of the reason why AOP was so widely adopted by the community.
    To my knowledge, there is nothing you can do with AOP that you can't with OOP. To me it's 6 of one, one-half-dozen of the other.
    Getting back to ThreadLocal's, someone from the core team from my company had serious leaks and he just took out all the ThreadLocal's just because of this. The problem was that in fact the code was not doing any clean-up. I guess it's so easy to blame TreadLocal's when in fact programmers are making them un-effective.
    One of the qualities I assign to elegant Java code is that it doesn't have much (if any) explicit cleanup. Objects should fall out of scope an become unreachable when they are no longer needed. Explicit cleanup is inherently inelegant and also fraught with error.

    IMHO ThreadLocals/InheritableThreadLocals are making context propagation among application layer so much cleaner and ellegant.
    So are you suggesting that this is the only solution to the context propagation problem? Couldn't foresight have avoided the need to use ThreadLocals?
  29. Re: Hard Core Java: ThreadLocal[ Go to top ]

    So are you suggesting that this is the only solution to the context propagation problem? Couldn't foresight have avoided the need to use ThreadLocals?
    Can you outline a solution that (a) doesnt require explicit passing of context information, and (b) doesnt require synchronization in a multithreaded environment? ThreadLocal happens to be a very simple, yet efficient, solution to the problem.
  30. Re: Hard Core Java: ThreadLocal[ Go to top ]

    So are you suggesting that this is the only solution to the context propagation problem? Couldn't foresight have avoided the need to use ThreadLocals?


    Can you outline a solution that (a) doesnt require explicit passing of context information, and (b) doesnt require synchronization in a multithreaded environment?

    ThreadLocal happens to be a very simple, yet efficient, solution to the problem.
    If I can start from sratch with a new Servlet spec, surely. Define the spec such that you can get the current request at any point just as you can get the current thread at any point. Can you explain why you think this would not be possible? The problem with ThreadLocal is that it can be a nice shiny hammer that makes everything look like a nail. It's reason for existence is for associating data with a thread. It's not a swiss-army-knife for all your data-passing needs.
  31. Re: Hard Core Java: ThreadLocal[ Go to top ]

    If I can start from sratch with a new Servlet spec, surely. Define the spec such that you can get the current request at any point just as you can get the current thread at any point. Can you explain why you think this would not be possible?
    Of course it is possible, and the cleanest and most performant way to implement it would be using ThreadLocal. What I am interested in is how you would implement that feature without ThreadLocal or synchronization.
    It's not a swiss-army-knife for all your data-passing needs.
    Thats true, but then again, I dont think that anyone thinks of it like that.
  32. Re: Hard Core Java: ThreadLocal[ Go to top ]

    If I can start from sratch with a new Servlet spec, surely. Define the spec such that you can get the current request at any point just as you can get the current thread at any point. Can you explain why you think this would not be possible?


    Of course it is possible, and the cleanest and most performant way to implement it would be using ThreadLocal.

    Not in my opinion. It's cleaner to use a OO approach and you can elimiate synchronization the way I gave above, by using Objects that are not shared by threads. If the context of the request is never accessed by more than one thread, there is no need for synchronization. Any approach that requires explicit cleanup in Java is suspect and definitely not a 'clean' approach.
    What I am interested in is how you would implement that feature without ThreadLocal or synchronization.
    I gave some examples above. A custom Runnable or Thread class. Using an OO design where the methods and the data are part of the same class and never letting this Object escape the thread. Let's take the HttpServlet class for example. Each method takes a HttpServletRequest. This is not an OO design. It's procedural. One possible (out of many) way to restructure this would be to make the contrustructor take the request and create a new instance for each request. Now none of these methods needs a request as a parameter because the request is part of the Object context. To avoid synchronization issues, you now only need to keep multiple threads from accessing the data at the same time. The server implementation can now be free to pass the object around to multiple threads (and possible incur syncronization costs) if it make sense for that implementation. The spec doesn't need to micromanage the implementation in order to allow people to use ThreadLocals.


    It's not a swiss-army-knife for all your data-passing needs.


    Thats true, but then again, I dont think that anyone thinks of it like that.
    When I read this from the blog article "Use a thread local variable (where each thread has a separate value) when you want to carry a value along without explicitly passing it from method to method down the call stack" it appears that the suggestion is that you should do this whenever the fancy strikes you. Maybe that's not Bob's intention but that's what I read.
  33. Re: Hard Core Java: ThreadLocal[ Go to top ]

    When I read this from the blog article "Use a thread local variable (where each thread has a separate value) when you want to carry a value along without explicitly passing it from method to method down the call stack" it appears that the suggestion is that you should do this whenever the fancy strikes you. Maybe that's not Bob's intention but that's what I read.
    The title of this article is "Hard Core Java", not "Java 101." I could have written about when and when not to use a ThreadLocal, but it's a gray area, and frankly it wouldn't be much fun for me. When it comes to software design, any advice to *always* do or not do something does more harm than good. Advising your audience to never use ThreadLocal is on par with telling readers to never use getters or to write unit tests with 100% coverage (both of which are also bad advice). You very well may think that there are appropriate uses for ThreadLocal, but you've only provided one side of the argument. I can tell you from experience that there are many uses for ThreadLocal which suffer not of the problems you've cited. You must make decisions to use or not use a ThreadLocal on a case by case basis; there are no hard and fast rules. Does using a ThreadLocal make your clients code easier or as easy to unit test? Does it make your API more intuitive and less confusing? Is there a chance your client can use your code without setting up the thread local? If so, you should take steps to minimize this possibility but still fail clearly when appropriate. That said, I've really only used ThreadLocal in "system" or "framework" code, but then again this is what I spend most of my time on. This is also why I equated ThreadLocals to static state at the end of the article. Both result in these non-explicit dependencies you're worried about; if you don't want any of those, you might prefer a functional programming language. Compared to statics, at least ThreadLocals can provide different values in different contexts (so if you decide later that a given singleton isn't so singelton any more, a ThreadLocal may help you fix your code with minimal effort). I've also been thinking about why developers often make ThreadLocal variables static and in turn equate them with global state. Without ThreadLocals, we have two dimensions of scope to think about: access (public, protected, package, private) and variable (static, instance, local, etc.). ThreadLocal adds a third dimension which can make the code more difficult to reason about (i.e. which instance do I end up with here?), so developers opt for "public static" and as a result only have to reason about the thread local scope.
  34. Re: Hard Core Java: ThreadLocal[ Go to top ]

    When I read this from the blog article "Use a thread local variable (where each thread has a separate value) when you want to carry a value along without explicitly passing it from method to method down the call stack" it appears that the suggestion is that you should do this whenever the fancy strikes you. Maybe that's not Bob's intention but that's what I read.


    The title of this article is "Hard Core Java",
    BTW, are you aware that there is an O'Reilly book of the (essentially) same name?
    not "Java 101." I could have written about when and when not to use a ThreadLocal, but it's a gray area, and frankly it wouldn't be much fun for me.

    That's all well and good for you but then I have to argue endlessly with people about why not to 'always' use StringBuffers for concatenation and now I'll be having to do the same with ThreadLocals. I guarantee somweone will read that article and start using ThreadLocals whenever they've coded themselves into a corner and some will use it very liberally. It would be nice to have a disclaimer so that when they point your your article I can point to the disclaimer.
    When it comes to software design, any advice to *always* do or not do something does more harm than good. Advising your audience to never use ThreadLocal is on par with telling readers to never use getters or to write unit tests with 100% coverage (both of which are also bad advice).
    I agree completely. I wish everyone understood this but many people don't.
    You very well may think that there are appropriate uses for ThreadLocal,
    Maybe. I guess it depends on how you interpret my comments in this thread: "There are definitely legitimate uses of ThreadLocal" "ThreadLocals are a perfectly good way to associate data with a thread when it is not feasible to customize the threads with Runnable Objects" "I've never suggested that ThreadLocals are not useful" I can see how it wouldn't be clear what my stance is on that.
    but you've only provided one side of the argument.
    Just as you did. We had avoided duplication of effort.
    I can tell you from experience that there are many uses for ThreadLocal which suffer not of the problems you've cited. [snipped] ThreadLocal adds a third dimension which can make the code more difficult to reason about (i.e. which instance do I end up with here?), so developers opt for "public static" and as a result only have to reason about the thread local scope.
    I have no argument with what you say here. I do avoid static variables but I avoid ThreadLocals more. The reason is that it's an obscure part of the JDK whereas static is a fundamental feature of the language. My only point is that I can't imagine why anyone with a clean slate design would choose to use ThreadLocals for anything other than for areas that are specifically dealing with threading concerns.
  35. Re: Hard Core Java: ThreadLocal[ Go to top ]

    FWIW, I wasn't arguing for ThreadLocals or even addressing when they should be used. I just said, if you're going to use them, here are some patterns for cleaning up after yourself and improving performance.
    My only point is that I can't imagine why anyone with a clean slate design would choose to use ThreadLocals for anything other than for areas that are specifically dealing with threading concerns.
    Here's one example: I'm implementing a DI container. I have an internal context object which I pass around internally and use to manage circular dependencies, etc. My framework allows users to provide their own custom factories. If the user's factory calls back into the container, I need to reuse the same context. I could pass the context to the user and force them to pass it back in, but this would require the user to pass the context object around. I would have to have a second set of methods which accept the context, and there's a chance the user would call the wrong method in which case I would wrongly create a new context. This also exposes my internal state to the user. They can hold onto it, prevent it from being reclaimed by the garbage collector, etc. Or, I could use a ThreadLocal, and the user remains completely and safely oblivious to the fact that I'm managing this context.
  36. Re: Hard Core Java: ThreadLocal[ Go to top ]

    FWIW, I wasn't arguing for ThreadLocals or even addressing when they should be used. I just said, if you're going to use them, here are some patterns for cleaning up after yourself and improving performance.
    I apologize if my tone came across as an attack. I've just had so many battles with people who have read something about an advanced technique but don't understand the subtleties, well... subtlety in general really. I just wanted to dampen the enthusiasm for this technique. Not that it isn't effective, it's just not a first choice technique.


    My only point is that I can't imagine why anyone with a clean slate design would choose to use ThreadLocals for anything other than for areas that are specifically dealing with threading concerns.


    Here's one example: I'm implementing a DI container. I have an internal context object which I pass around internally and use to manage circular dependencies, etc. My framework allows users to provide their own custom factories. If the user's factory calls back into the container, I need to reuse the same context.

    I could pass the context to the user and force them to pass it back in, but this would require the user to pass the context object around. I would have to have a second set of methods which accept the context, and there's a chance the user would call the wrong method in which case I would wrongly create a new context. This also exposes my internal state to the user. They can hold onto it, prevent it from being reclaimed by the garbage collector, etc.

    Or, I could use a ThreadLocal, and the user remains completely and safely oblivious to the fact that I'm managing this context.
    To me this would either fall under a thread-specfic issue or a 'there's no other choice' issue. This sounds like a technique that deals with re-entrance, which BTW, was one of the most interesting and helpful parts of your blog article, I thought. I guess the only part of your article that bugged me was, the first sentence "Use a thread local variable (where each thread has a separate value) when you want to carry a value along without explicitly passing it from method to method down the call stack..." Maybe your intention was not to suggest when to use ThreadLocals but some people will interpret that sentence as just that. Knowing some of the developers that I do, they will read that and think "hmm, it is annoying to have to declare and pass paramters. I'll use ThreadLocals instead." I just seems like a statement ripe for someone to read into.
  37. Re: Hard Core Java: ThreadLocal[ Go to top ]

    I guess the only part of your article that bugged me was, the first sentence "Use a thread local variable (where each thread has a separate value) when you want to carry a value along without explicitly passing it from method to method down the call stack..." Maybe your intention was not to suggest when to use ThreadLocals but some people will interpret that sentence as just that. Knowing some of the developers that I do, they will read that and think "hmm, it is annoying to have to declare and pass paramters. I'll use ThreadLocals instead." I just seems like a statement ripe for someone to read into.
    Ha ha. You're right. I'll spend more time on the introduction in the next installment. ;)
  38. Re: Hard Core Java: ThreadLocal[ Go to top ]

    I love discussions that actually come to a tidy conclusion. All-in-all, good article, though. It introduced me to some approaches I hadn't considered.