
[java] Threading Probs
If anyone could offer advice on this it would be greatly appreciated
I started playing with Java''s socket code to get familiar with it and wrote a small messaging application. The application, based from JFrame, runs the networking code through another thread that it holds. The primary UI thread and the networking thread talk to each other via a set of synchronized message queues. The client seems to be able to connect fine to the server (the app can function as either) but then the networking thread seems to stop cold. The primary UI thread has an Timer to check for new messages and when I walk through it in the debugger that is basically I''ll I can see executed - the networking thread never seems to come to life again (though it did initially; it manages to connect). The Timer executes every second, though for kicks I slowed it to 30 seconds, but still the result is the same: I find myself simply walking through my action code from my Timer.
Question: why did the network thread quit on me? Would I be better served by placing all the UI in an actual thread (as opposed to it being the JFrame/main implementation) where I can force it to sleep or yield? Is there something else I can do to bring the network thread back to life? Perhaps a timer of its own?
Thanks for any help,
Sieggy

August 19, 2001 02:21 PM
It would be good if you could post the network code but if you are using TCP sockets you may want to make sure that the sending application flushes the stream connected to the socket when it wants to send data, otherwise the data written to the stream may be buffered and your receiving thread blocks while reading the stream (since it never receives any data). If you are using ObjectInput/OutputStream streams to transfer serialized object you will also want to flush the output streams right after you create it so the initialization of the receiving input stream gets done.
Henry
Henry
I''m using ObjectStream and I am flushing the stream. I don''t think the problem is the network since I send an initial hello message to the server and it comes across fine. Its just anything after does not, though in the debugger the socket still seems to be valid. I''m not recieving any exceptions from the socket so, again, I don''t think its that.
My believe its the threading is that the idle processing to check for messages (in the network thread) never seems to be executed. The network threads run() method:
//Run Thread Interface
public void run()
{
//init
boolean ok = false;
//construct the connection
//server mode
if (config.getMode() == ConfigParams.SERVER) {
ok = connectServer();
}
//client mode
else {
ok = connectClient();
}
//start process, only if we are ok
if (ok == true) {
while (ok == true) {
//loop indefintely
//listen for new connections if i''m a server
if (config.getMode() == ConfigParams.SERVER) {
listenForConnections();
}
//recieve messages
listenConnections();
//send messages
sendMessages();
//quiet down for a sec
try {
sleep(1000);
}
//catch sleep end
catch (InterruptedException ex) {
//do nothing
}
}
}
}
The sendMessages() method never comes about. Any thoughts?
Sieggy
My believe its the threading is that the idle processing to check for messages (in the network thread) never seems to be executed. The network threads run() method:
//Run Thread Interface
public void run()
{
//init
boolean ok = false;
//construct the connection
//server mode
if (config.getMode() == ConfigParams.SERVER) {
ok = connectServer();
}
//client mode
else {
ok = connectClient();
}
//start process, only if we are ok
if (ok == true) {
while (ok == true) {
//loop indefintely
//listen for new connections if i''m a server
if (config.getMode() == ConfigParams.SERVER) {
listenForConnections();
}
//recieve messages
listenConnections();
//send messages
sendMessages();
//quiet down for a sec
try {
sleep(1000);
}
//catch sleep end
catch (InterruptedException ex) {
//do nothing
}
}
}
}
The sendMessages() method never comes about. Any thoughts?
Sieggy
Hmm.. A few minor things. They don''t answer your question, but they may make it easier for us to help.
(ok == true) is redundant. Just use (ok).
This is redundant:
In the case where ok is false before the first iteration, simply saying while (ok) means that the code inside the loop will never be executed.
Use source tags when posting code on this board. It makes the code readable, preserving indentation among other things.
Now, I do have one guess as to what''s going on. Every time through the loop, you have your server wait for a new incoming connection (I think... It''s tough to figure out exactly, given that you didn''t post the source for your methods), before it waits for any incoming messages. It looks like your whole design is flawed.
The typical solution for this is to put the code to check for new incoming connections in one thread, and have it spawn a new thread for every incoming connection it gets. The threads for each incoming connection sit in a loop that repeatedly reads the next bit of input, then processes it. None of those threads calls sleep explicitly. Rather, they block while waiting for input or a new incoming connection, and due to that blocking behavior they don''t eat much CPU time.
(ok == true) is redundant. Just use (ok).
This is redundant:
|
In the case where ok is false before the first iteration, simply saying while (ok) means that the code inside the loop will never be executed.
Use source tags when posting code on this board. It makes the code readable, preserving indentation among other things.
Now, I do have one guess as to what''s going on. Every time through the loop, you have your server wait for a new incoming connection (I think... It''s tough to figure out exactly, given that you didn''t post the source for your methods), before it waits for any incoming messages. It looks like your whole design is flawed.
The typical solution for this is to put the code to check for new incoming connections in one thread, and have it spawn a new thread for every incoming connection it gets. The threads for each incoming connection sit in a loop that repeatedly reads the next bit of input, then processes it. None of those threads calls sleep explicitly. Rather, they block while waiting for input or a new incoming connection, and due to that blocking behavior they don''t eat much CPU time.
Thanks for that advice, it probably would make more sense. As it stands right now all the networking is a single thread. The communications manager holds a LinkedList of clients as well as the listener and it iterates through them to check for new messages. Unfortunately it doesn''t deal with the parculiar situation in which the thread stops executing. There is something I missed in setting up my interaction between the networking thread and the ui. From my ui piece:
In the debugger all I seem to get are action events for checking for new messages. I put a manual trace in the communication managers sendMessages() function, but it never executes. If I walk through the debugger it seems to "stop" running the network thread.
Sieggy
|
In the debugger all I seem to get are action events for checking for new messages. I put a manual trace in the communication managers sendMessages() function, but it never executes. If I walk through the debugger it seems to "stop" running the network thread.
Sieggy
August 20, 2001 10:19 AM
I don''t see any obvious problems with your code but if the connectServer executes successfully but the sendMessages method does not then you might want to swamp the area between them with debug message to see where it hangs. You should also check that the connectServer method is the one that gets called and that it returns true. When those checks are done you should know in which method it hangs and fill that method with debug messages etc. A thread will not normally just die unless you have some other high-priority thread that performs some expensive busy-wait and consumes all the resources.
Henry
Henry
Sieggy,
Try checking out the following article:
http://developer.java.sun.com/developer/technicalArticles/Programming/Stacktrace/
It explains the various portions of a Java Stack trace and it is useful because you can examine what all of the threads of your application were doing at the time the trace is generated.
You can generate a stack trace by pressing CTRL-BREAK in a dos window or if you are on a unix box you can pass a signal to your process to generate a dump.
Try getting a dump and examining what your network thread is doing.
Tyler.
Try checking out the following article:
http://developer.java.sun.com/developer/technicalArticles/Programming/Stacktrace/
It explains the various portions of a Java Stack trace and it is useful because you can examine what all of the threads of your application were doing at the time the trace is generated.
You can generate a stack trace by pressing CTRL-BREAK in a dos window or if you are on a unix box you can pass a signal to your process to generate a dump.
Try getting a dump and examining what your network thread is doing.
Tyler.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement