I'm jumping into the middle of a conversation that I haven't followed closely, so this could be inapplicable, but it seems to me that there is an option #4, namely Avalon-style explicit provisioning of a Logger when the DatabaseManager is constructed.
Just a thought... Gary On Tue, 19 Nov 2002, at 20:00 [-0000], Kevin Smith ([EMAIL PROTECTED]: > Here's the threading issue I see: > > public class DatabaseManager > { > private transient Logger logger; > > public Database getDatabase() { > Logger logger = getLogger(); > logger.debug("Getting database"); > // do something here and return database > } > protected Logger getLogger() { > if(logger == null) > logger = LogFactory.getLogger(getClass()); > > } > } > > If two threads call getDatabase() at the same time, there is a chance that you > could wind up allocating two loggers when only one is needed. Since the > logger is thread-safe, we need to make getting a reference to a logger > thread-safe, too. > > There are three ways of doing it: > > 1) Synchronize getLogger() - This introduces synchronization overhead every > time you need a logger. > > 2) Synchronize all methods that call getLogger() - Ugly. > > 3) Make the logger a static variable - This moves the initialization of the > logger to when the class is loaded and thus, removes any threading issues. > The penalty for such a refactoring is having one line of duplicate code in > each class: > > private static Logger logger = LogFactory.getLogger(Database.class.getName()); > > That's why I was suggesting using #3. > > --Kevin > On Tuesday 19 November 2002 07:52 pm, Kevin Ross wrote: > > >Obtaining loggers might be a bad example. All I'm saying that in my > > > > experience, this kind of resource initialization scheme is better off > > being thread safe from >the start. It eliminates a whole family of bugs > > that you need to worry about down the road. > > > > Agreed, but in the case of logging, I believe you should err on the side > > of performance for the greater good, the 80%+ case. Bothering with > > paranoid initialization (synchronization) makes everyone instance pay > > the price. > > > > Just got your next message. I'll say it one more time, WHAT thread > > safety issues???? The logger is responsible for thread safety. I don't > > implement synchronization when initializing or using a Logger, because > > it is unnecessary for the client to do so. I haven't for years now, and > > I haven't had one problem in organizations with traffic from a few > > thousand hits a day, to a few million. > > > > Duplication of code is one of the fundamentally wrong things to do in OO > > programming, and I agree, therefore I stay away from it. > > > > -Kevin Ross > > > > Kevin A. Smith wrote: > > > I just thought I'd bring it up. Personally, I err on the side of > > > paranoia when I can. I don't enjoy debugging threading issues. > > > > > > If the LogFactory is recycling logger instances, then at most you pay > > > the price of one extra method call. BUT, if the LogFactory is creating > > > a new logger per call, then you're (potentially) paying the price of > > > creating an object that won't be used and an extra method call. > > > > > > Obtaining loggers might be a bad example. All I'm saying that in my > > > experience, this kind of resource initialization scheme is better off > > > being thread safe from the start. It eliminates a whole family of bugs > > > that you need to worry about down the road. > > > > > > --Kevin > > > > > > -----Original Message----- > > > From: Kevin Ross [mailto:[EMAIL PROTECTED] > > > Sent: Tuesday, November 19, 2002 2:30 PM > > > To: [EMAIL PROTECTED] > > > Subject: Re: LogFactory.getLogger() > > > > > > Threading issues?? I knew someone would bring that up. Thread > > > safetyness is the responsibility, gladly accepted by a logger > > > instance, not on the classes using it. There is NO reason why we > > > need paranoid checking here to only get one instance, since it is > > > the responsibility of the logging implementation to even provide > > > the instance in the first place. Do you really think you'll get > > > different instances? Probably not, worst case scenario, you call > > > Logger.getLogger() twice and initialize your instance twice in a > > > race condition. Since it is of zero consequence either way, there > > > is no reason to do it differently. If you are particularly > > > worried, just do: > > > > > > private transient Logger logger = LogFactory.getLogger(getClass()); > > > > > > You CANNOT use MyClass.class and have MySubClass.class show up in > > > the log statements, since this is static. You must use dynamic > > > initialization. > > > > > > -Kevin > > > > > > Kevin A. Smith wrote: > > >> That doesn't look thread-safe to me. You'd need to somehow > > >> synchronize access to getLogger() to eliminate a race-condition > > >> on the if(logger == null) test. > > >> > > >> While its a bit more typing, I prefer: > > >> > > >> private static Logger logger = LogFactory.getLogger(MyClass.class); > > >> > > >> or > > >> > > >> private static Logger logger = > > >> LogFactory.getLogger(MyClass.class.getName()); > > >> > > >> No threading issues and is pretty easy to read and understand. > > >> > > >> --Kevin > > >> > > >> -----Original Message----- > > >> From: Kevin Ross [mailto:[EMAIL PROTECTED] > > >> Sent: Tuesday, November 19, 2002 2:18 PM > > >> To: Vladimir R. Bossicard; [EMAIL PROTECTED] > > >> Subject: Re: LogFactory.getLogger() > > >> > > >> As I mentioned in my previous message, this is a poor way to > > >> obtain a logger, especially if you have deep inheritance > > >> heirarchies. Since I'm a big fan of OO programming, and my > > >> heirarchies are especially deep, I find the static way of > > >> obtaining a logger invalid. > > >> > > >> Try this: > > >> > > >> public class AbstractLoggable{ > > >> > > >> private static transient Logger logger; > > >> > > >> protected Logger getLogger(){ > > >> > > >> if( logger == null ){ > > >> > > >> logger = Logger.getLogger(getClass()); > > >> } > > >> > > >> return logger; > > >> } > > >> } > > >> > > >> whallah! efficient OO programming with an accessor for > > >> subclasses and the proper class name to go with it! > > >> > > >> -Kevin Ross > > >> > > >> Vladimir R. Bossicard wrote: > > >>>>Logger.getLogger(getClass()) at least, whether or not you use the > > >>>> string name is of no consequence. > > >>> > > >>>have you ever tried to call a non-static method within a static > > >>> reference? > > >>> > > >>>if you get this working: > > >>> > > >>> private static Log log = LogFactory.getLog(getClass()); > > >>> > > >>>I give you a high-five. > > >>> > > >>>-Vladimir > > >>> > > >>>-- > > >>>Vladimir R. Bossicard > > >>>www.bossicard.com > > >