Java Thread will not stop on IO

I was under the impression that the Java Thread will stop and give other threads a chance to do some work while blocking I / O operations (e.g. Socket.read () or DataGramsocket.receive ()). For some reason, in my multithreaded network application, a call to the receive () method causes all my other threads to starve (the thread called receive () becomes a big boss and never relinquishes control, thereby blocking forever!)

Why is this happening? I used to have the same exact application, but instead of UDP, it was TCP based. Socket.read () would always suspend the Thread and let others run for a bit if it blocked for too long.

- additional information - The TCP version of my user thread was the following code: http://www.dwgold.com/code/proxy/proxyThread.java.txt

My new code (UDP version) is almost the same, but slightly changed the use of UDP methods and style. Then I created two of these threads and started running both. The first thread always blocks and never lets the other run on the UDP version.

+2


source to share


3 answers


You seem to be using an InputStream, and according to the JDK docs for InputStream.read () , it blocks reading exactly as you described - until data is received, end of file is reached, or an exception is thrown.

So the question for me is, why does the TCP version of your code allow the block to be aborted? It doesn't seem to make any sense. Perhaps your TCP code is breaking the reads into discrete, short enough packets that the stream has the ability to jump between the individual read () calls?



Further I see that the difference is that the TCP version of your code receives data via the InputStream provided by the Socket, whereas the UDP version of your code receives data directly from the DatagramSocket's own receive () method. So I guess this is just a fundamental difference between the functionality offered by these two (InputStream.read and DatagramSocket.receive). Have you thought about using DatagramPacket.setSoTimeout to set a timeout on the socket receive block and then catch the SocketTimeoutException when it was thrown by the receive () call, what's the time? You must implement this in order to achieve what you want.

UPDATE : Even further, it looks like the DatagramSocket.receive method is syncing . So the way to explain the behavior you're seeing is that you start two threads that try to use the same DatagramSocket instance - if two threads try to get () on the same DatagramSocket instance, one will block until then until it is done and the other is blocked. (There's a post on the Sun forums that describes this , too.) Perhaps it goes like this: Are you reusing the same DatagramSocket for both threads?

+1


source


This may be due to the fact that Java threads are user-level threads (as opposed to kernel-level threads). One kernel thread can contain multiple user-level threads. However, if one user-level thread is waiting for io, the kernel has no way of putting just that user-level thread on the wait queue, it can put the entire kernel thread on the wait queue (user-level threads are scheduled at the user level, not at the kernel level). As a result, one user-level thread waiting for io can / will block all other user-level threads (from that kernel thread).



0


source


There is really no explanation for the behavior you describe that reading into an InputStream from a Socket should pause "all other streams". You accidentally start multiple threads that are all reading from the same socket, and what do you really mean that all those threads are hanging? In this case, I expect the data read from the socket to be split randomly among streams.

-1


source







All Articles