Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!eternal-september.org!feeder.eternal-september.org!mx04.eternal-september.org!.POSTED!not-for-mail From: Steven Simpson Newsgroups: comp.lang.java.programmer Subject: Re: Wormholes Date: Tue, 04 Sep 2012 14:18:33 +0100 Organization: A noiseless patient Spider Lines: 46 Message-ID: <9mbhh9-mce.ln1@s.simpson148.btinternet.com> References: <0ska4895k2mp2j5fb5p4qnue7lsbdpoeoo@4ax.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Info: mx04.eternal-september.org; posting-host="4ee28819d39fc5800514fcb4380da8e5"; logging-data="6201"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/GWLEQeBQnAmwDTFjSCzY2MJgQVkaLizU=" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120827 Thunderbird/15.0 In-Reply-To: <0ska4895k2mp2j5fb5p4qnue7lsbdpoeoo@4ax.com> Cancel-Lock: sha1:hY+1mVHSPQ5ZllerxNQae3np5J0= Xref: csiph.com comp.lang.java.programmer:18532 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 suppose you could do something similar without threads, e.g.: class Context { Map, Object> items = new IdentityHashMap<>(); } class ContextLocal { void set(Context ctxt, T val) { ctxt.put(this, val); } T get(Content ctxt) { return (T) ctxt.get(this); } } Then you'd refactor once to pass Context through the chain. x creates a static ContextLocal myContext, and one Context ctxt for each call, and sets up myContext.set(ctxt, value) before the call. y calls myContext.get(ctxt) to get the value. -- ss at comp dot lancs dot ac dot uk