AutoImportRun - contains main() method and starts up three threads
FileGetter - two of the threads started are of this type, each thread gets a different parameter so that each thread is "getting" a different type of file FileProcesser - the third type of thread started - this object processes the files "gotten" by the FileGetter objects
TextDisplay - this is a class that creates a GUI that displays messages written by each of the three threads - an instance of this class is started by each of the three threads that are running
So, AutoImportRun creates two FileGetters and one FileProcesser thread as soon as it starts, each of the three threads each creates it's own TextDisplay to which it writes messages as soon as it starts up. The net result is that we end up with three threads running with three GUI screens showing what each is doing.
Problem - Occationally, not all the time, one of the three threads that AutoImportRun starts would fail to start. It could be any of the three it was never predictable. When the failure occurred, an error message would display very quickly and disappear and I know it referred to "swing" which is what TextDisplay uses.
My guess at the cause - Since each of the three threads instantiates a TextDisplay object almost at the same time, there is some type of conflict or resource that cannot be accessed or shared by multiple objects at the same time? Maybe accessing the TextDisplay.class file at the same time?
My fix - I put in a wait() for 10 seconds before the start of each thread in AutoImportRun. This has stopped the problem, all three threads always come up (at least for the past day when testing). I think this is a good fix but I'm not sure if I understand WHY it was a problem in the first place.
Hopefully one of the more seasoned Swing coders can correct me if I get this wrong (it's been a looong while since I've done any Swing work), but from my recollection Swing has very specific rules about things that must be one the main event Thread and things that should be run off of it.
My guess is that Swing does not like that you are creating GUI objects from three different Threads. This has nothing to do with multiple Threads instantiating the same class. The problem is that they're doing Swing operations.
The quick fix that should solve the problem (as opposed to mitigate it as you have done, i.e. solve it "most of the time" but not guarantee success) is to instantiate the GUI objects in your main thread and pass their references to your Threads.Using this pattern, only one Thread is doing all the Swing stuff, avoiding the intermittent problem you were seeing and could see if you run on hardware with different performance characteristics.
As you go forward, you may find that having the three Threads operate on their GUI TextDisplays causes other strange behavior, but at this point I will be totally guessing. Any Swing guru care to elaborate?
A couple notes about this as some free advice. Unless you're alternig the behavior of the Thread itself, it's best to make your tasks (FileGetter and FileProcessor) implement Runnable -- override run() method -- instead of extend Thread. This allows a more flexible design as you go forward, better reuse, and the possibility of using with a thread pool or other architecture.
Also, you probably pass the two FGs into the FP, so you'll want to instantiate the FGs outside of the Threads, store the references, and pass them to the new Thread() calls and the new FP() call. You're doing some complex stuff here, so I've assumed you can handle that part on your own.
If you have any questinos or need clarification, let's hear it. [ February 17, 2005: Message edited by: David Harkness ]
It's good for Swing apps to get long running processes off the main Swing thread, so your design is doing good things. But Swing doesn't like it when other threads try to update the UI. I've had symptoms like messages that didn't appear until the next update came through or until I resized the window. I haven't had threads die from Swing issues, but that might be your problem. Or not.
The solution is in SwingUtilities.invokeLater() or invokeAndWait(). You put the update code into a Command and give the Command to Swing. Swing invokes the command on its own thread.
This sounds like a neat assignment - assuming it's homework or a course lab. Keep us posted how it goes.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Wow, even better. It's still a neat problem, but we don't have to do the broad hints we usually frustrate students with.
I wrote a file downloader to pull logs off web servers. It can open any number of download threads (per configuration). I put a status panel per thread onto my main window and use a little pub-sub framework to get status updates from each downloader to the panel right. The panels use SwingUtilities to do the actual updates. Before I learned SwingUtilities I had all kinds of strange UI behavior. Sounds like you might be in the very same place. Hope that helps!