Path: csiph.com!usenet.pasdenom.info!gegeweb.org!de-l.enfer-du-nord.net!feeder1.enfer-du-nord.net!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Robert Klemme Newsgroups: comp.lang.java.programmer Subject: Re: Wormholes Date: Wed, 05 Sep 2012 21:51:26 +0200 Lines: 44 Message-ID: References: <0ska4895k2mp2j5fb5p4qnue7lsbdpoeoo@4ax.com> <9mbhh9-mce.ln1@s.simpson148.btinternet.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net ACZlKy7G0sxg2YOr71xVjQFTaByeMmRrIt+z7K37asuy225CcHshUE1asjEi1hmRg= Cancel-Lock: sha1:fOxAa/D7sVymPAQJA3WJFndslDY= User-Agent: Mozilla/5.0 (Windows NT 6.0; WOW64; rv:15.0) Gecko/20120824 Thunderbird/15.0 In-Reply-To: <9mbhh9-mce.ln1@s.simpson148.btinternet.com> Xref: csiph.com comp.lang.java.programmer:18558 On 04.09.2012 15:18, Steven Simpson wrote: > On 04/09/12 02:12, Roedy Green wrote: >> Somehow I must pass information down the long chain from x to y. This >> means changing the signatures of all the intermediate methods, and >> adjusting code to the new way. This can cause ripples incommensurate >> with the triviality of the change. > > Assuming that you can't improve your structure or refactor, a > ThreadLocal might be appropriate as your wormhole. > > I've had to do this lately. The intermediate steps were recursive calls > through a hierarchy. y was a custom implementation of a node nested in > that hierarchy. x started off the recursive call. > > If I was only using the hierarchy once, for one call by x, I would have > simply embedded the context in y. But the hierarchy was to be re-used, > and y needed a different context for each call by x. Also, calls by x > could be concurrent. > > However, I could guarantee that any single call by x would invoke y by > the same thread. That allowed the context to be passed by a > ThreadLocal, set by x just before the call. I knew finally someone would suggest ThreadLocal for this. This might be even worse than global variables, especially since you pass hidden state which usually makes testing more difficult. The proper approach would be to pass the state down the call chain. IMHO the best usage for ThreadLocal is to cache state *inside a class* if calls may be concurrent and the cost of creating the state is significantly high. But using it to pass information between classes because one wants to avoid adding method parameters is asking for trouble. Also, you need to be aware that the lifetime of these objects can be quite long (there was a discussion about various aspects of ThreadLocal in light of thread pools here earlier). Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/