Heh, boy did I mangle the word physicist - twice! ----- Original Message ----- From: "Mike Bresnahan" <mike at fruitioninc.com> To: <tclug-devel at mn-linux.org> Sent: Tuesday, July 17, 2001 10:45 AM Subject: Re: [TCLUG-DEVEL] Java Interfaces and multi-extends? > We may end up having to agree to disagree. Heh > > Let me start with a disclaimer. I have been guilty more than once of > creating overly complex solutions as a result of my passionate pursuit of > elegant, generic, and beautiful code. I think it is the > mathematician/physitist in me. I'm always seeking to make my code more and > more general and semmetric much like mathematicians and physiticts are > always seeking to find the underlying thereom or the grand unified theory. > So I understand first hand your concerns about unnecessary code complexity. > However, I do not feel I am guilty in the current context. > > I create a new class called Tuple so that I can change the implementation > later without effecting client code - basic data abstraction. I also find > that the name more clearly describes the class's role. Additionally, I may > want to add more features. For example, I may want the tuple to maintain > order of the elements. java.sql.ResultSet does this. You can retrieve a > column via its name or its index. Hashtable does not allow this. > > I feel the producer-consumer pattern is not nearly as complex as you're > making it out to be. Here's some sample code off the top of my head based > on that found in Patterns in Java. > > public class Producer implements Runnable { > private Queue queue; > public void run() { > Thingy thingy = getThingy(); > queue.push( thingy); > } > } > > public class Consumer implements Runnable { > private Queue queue; > public run() { > Thingy thingy = queue.pull(); > } > } > > public class Queue { > private java.util.LinkedList list = new java.util.LinkedList(); > public synchronized void push( Thingy thingy) { > list.add( thingy); > notify(); > } > public synchronized Thingy pull() { > if( list.size() == 0) { > try { > wait(); > } > catch( InterrruptedException ex) { > } > } > return (Thingy)list.removeFirst(); > } > } > > I'd also like to make the point that there is more to software quality than > source code simplicity. In fact, the most important software quality > criteria have nothing to do with source code, rather they have to do with > user satisfaction. User's really don't care how simple, beautiful, or > maintainable your code is. They only care how well it performs the work > they ask of it. By not using the producer-consumer combined with a thread > pool you seem to favor code simplicity over user satisfaction. > > I also believe that code simplicity is not always the road to > maintainability. For instance, hard coding the number of worker threads > into the application may be simple, but it is a maintainence headache. > People supporting the software in the future will have to make code changes, > do testing, and do a rollout simply to do some simple performance tuning. > Hard coding anything like that is a big no-no in my book. > > I've had to rewrite more than once code that used polling instead of proper > wait/notify semantics, because of the performance problem it was causing. I > think 20 instructions per poll is an overly conservative estimate. Can Java > get anything done in 20 cyles? Additionally, if you plan to run this > application on a server shared by other applications you simply aren't being > a good neighbor by wasting precious cpu cycles. Even with today's 1Ghz > processors, cpu cycles are not a renewable resource. Perhaps you should > reconsider your refusal to sign the Kioto Protocol, Mr Bush. > > Mike > ----- Original Message ----- > From: "Bill Gladen" <nobody170 at yahoo.com> > To: <tclug-devel at mn-linux.org> > Sent: Tuesday, July 17, 2001 6:23 AM > Subject: Re: [TCLUG-DEVEL] Java Interfaces and multi-extends? > > > > Okay, today's preface will be that I'm grumpy. > > On that note, I shall withdraw yesterday's preface and state that He's > > flat out wrong. :-) > > > > First, a toString() is one of the most trivial things you can put in a > > class, and generally not considered very important unless you need to > > debug your stuff. Try writing a clone() (a deep clone, no cheating) or > > implement the serializable interface (again with deep serialization) on > > the Tuple class. > > > > As for data validation, and not putting any in, why do you even have a > > Tuple class? If there's no validation, and it's just a placeholder for > > data, then just use a HashMap. If you need other functionality, write > > a utility class (it can even be completely static) that has a method to > > return a string from a HashMap. > > > > KISS = Keep It Simple, Stupid. > > > > As for the synchronization and implementation of jobQueue.hasNext(), > > here is the revised code. Note the lack of reinvented wheels. > > > > ... > > LinkedList jobQueue = new LinkedList(); > > for( i = 0; i < NUMBER_OF_PROCESSING_THREADS; i++ ){ > > Thread t = new Thread( new Runnable(){ > > public void run(){ > > Job job; > > while( true ){ > > job = null; > > synchronized( jobQueue ){ > > if( ! jobQueue.isEmpty() ){ > > job = (Job)jobQueue.removeFirst(); > > } > > } > > if( null != job ){ > > try{ > > job.runJob(); > > }catch( Throwable t ){ > > // handle this. > > } > > }else{ > > try{ > > sleep( SLEEP_TIME ); > > }catch( InterruptedException ie ){ > > } > > } > > } > > } > > } ); > > t.setDaemon( true ); // VERY IMPORTANT!! > > t.start(); > > } > > > > That's all off the cuff, so if there are syntax errors, don't nit-pick. > > > > As for the sleep vs. wait/notify, yes this will use cycles, but it will > > probably be about 20 instructions per idle cycle (it would be about 3, > > but synchronization is expensive), which translates into less than .1 > > millisecond on today's processors. If you are sleeping for 1 second, > > .01% is not enough to worry about. > > > > This way, the synchronization, processing, and run logic is in one > > place. > > > > If you implemented the classic producer/consumer pattern, you'd > > probably have 3 extra classes, and if you were using a pooled resource > > pattern for the Threads, that would be another 2 or 3 classes, and if > > you were using the Factory pattern to create the threads (so you could > > change the subclass of Thread or Runnable you used without changing any > > code) that would be ANOTHER 2 classes AND a properties file... > > > > If you think I'm just going off the deep end here, I've seen this kind > > of code. Using it is a serious nightmare. > > > > Bill > > > > > > > > > > > _______________________________________________ > tclug-devel mailing list > tclug-devel at mn-linux.org > https://mailman.mn-linux.org/mailman/listinfo/tclug-devel