I have a Thread (let's say T1) which reads data from socket:
public void run() {
while (running) {
try {
BufferedReader reader = new BufferedReader( new InputStreamReader(socket.getInputStream()) );
String input = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Another Thread (lets say T2) try to finish the program in one of its method. Therefore T2 does the following:
T1.running = false;
socket.close();
Here is this scenario for which i couldn't find a solution:
T1 is active and waiting for some input to read i.e. blocking.
context switching
T2 is active and sets running to false, closes the socket
context switching
because T1 was blocking and T2 closed the socket, T1 throws an Exception. What i want is to catch this SocketException. i can't put a try/catch(SocketException) in T1.run(). So how can i catch it in T1's running-method? If it's not possible to catch it in T1's running, then how can i catch it elsewhere?
PS: "Another question about the Thread Debugging"
Normally when i debug the code step by step, i lose the 'active running line' on a context switch. Let's say i'm in line 20 of T1, context switch happens, let's assume the program continues from the 30.line of T2, but the debugger does not go/show to the 30.line of T2, instead the 'active running line' vanishes. So i lose the control over the code. I use Eclipse for Java and Visual Studio for C#. So what is the best way to track the code while debugging on a context switch ?
For your problem assuming you are using a Thread Pool maybe you should make a ThreadFactory that installs a Thread.UncaughtExceptionHandler on all Threads and then invoke your work with execute() on the ExecutorService instead of submit().
For you problem with debugging maybe you should read
http://msdn.microsoft.com/en-us/library/ms164746.aspx
Your code has several other problems so I'll address them all at the same time.
You must create the BufferedReader outside the loop. Otherwise you will lose data in the buffers being discarded each time around the loop.
You must test the result of readLine() for null. If you get it, you must close the BufferedReader and exit the loop.
If you get any exception you must also close the BufferedReader and exit the loop.
What i want is to catch this SocketException.
So catch it.
I can't put a try/catch(SocketException) in T1.run().
You must. No choice. You have to completely rewrite it anyway because of the above items.
Related
Maybe I'm thinking to complicated, but I have the following situation:
I have a class Server.java extending Thread with the following relevant part of the code:
public void run() {
while(listening) {
try {
ServerThread cst = new ServerThread(serverSocket.accept());
cst.start();
} catch (IOException e) {
listening = false;
System.out.println(e.getMessage());
}
}
}
My ServerThread then handles all the incoming stuff.
My question now is, if there is any possibility to stop this Thread (Server) like for example over the command line.
I tried to add a new class, that would handle command line input and .interrupt() this Thread, but that kinda just made a big mess..
Here's one way:
Provide a setter for listening that can be accessed from another class/thread.
Set a reasonable timeout (say, 1 sec) on the ServerSocket and handle the SocketTimeoutException.
To stop the thread, set listening to false and within 1 second the thread will stop. If you want finer control, investigate the async I/O classes in java.nio.
You can define listening as volatile, with a setter and set that to false from another class whenever you want to stop the Thread.
Im calling ObjectInputStream all the time in while loop with statement true:
while(true){
//send data
}
but at moment when closing Socket, ObjectInputStream and rest i got multiple Exception Socket closed (actualy because i close it).
The question: what statement can i put in while loop to check ObjectInputStream is not closed?
Edit: Socket.isConnected() dont give good result
whole method
private void dataTransfer(){
try {
while(!con.isClosed()){
String message = (String) input.readObject();
ChatWindow.getMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Your problem is probably multithreading asynchronization.
While the while runs outside the EDT, windowClosing() runs inside. Therefore it may check the isClosed() before windowClosing() was actually called, and execute the loop code after that.
As in similar cases, the best way is to use synchronization, but it's not the best idea in the EDT. Use a new thread in the windowClosing() method that closes the stream and synchronize that.
I am having a scenario :
I have a thread which is calling a method where i use Default HTTP client to execute a request. for getting the response I open an InputStream and use a Buffred Reader to read the stream.
While(s = buffer.readline .... )
Inside the while loop i keep looking at the response and see for a string " Hello " ...If i get the string i send the response object back ..
The While loop executes till i get the string
The while loop executes till i press the back key ( android )
Now the scenario works for my 1st point. But i face issue in the 2nd point.
When i press back key, i need to stop my thread.
but i am not able to do it. I tried :
thread.destroy
thread.interrupt
thread = null
None of the above works. In fact my thread is always running...
I am not clear if the issue is with Thread or the issue is with the While loop of the stream.
Because i see that the while loop is executing always..
Please help me the best way i can solve this issue...Whether close the thread or close the stream.
Please help me find way to close the stream and close the thread.
thread.destroy() is deprecated. Do not use it.
The safest way to stop an IO bound thread is by interrupting it.
The thread's logic must cooperate by (1) checking for isInterrupted() status and
(2) catching InterruptedException exception.
It is important that both #1 and #2 above will be handled. interrupt()ing a
thread can in some occasions result in exceptions and in others in setting of
status with no exception!
A safe thread implementation goes like this:
class MyThread {
private volatile boolean wasStopped;
public void run() {
try {
while (!Thread.currentThread().isInterrupted() && !wasStopped) {
do_thread_work();
}
} catch (InterruptedException e) {
return; // gracefully stop thread
}
}
public void gracefullyStop() {
wasStopped = true;
this.interrupt();
}
}
To stop the thread call
thread.gracefullyStop();
This pattern will work fine as long as the thread logic function (do_thread_work)
will not internally catch & dismiss InterruptedException. Be aware.
You will see other implementations that rely solely on isInterrupted() check
without the additional wasStopped flag. I think this is a bad practice.
Why?
Because if the interrupt() was raised while the thread was in a waiting mode
i.e. inside functions wait() join() or sleep(), the thread will indeed be woken,
but its interrupted status will be set to false.
Good luck.
This question has no doubt been asked in various forms in the past, but not so much for a specific scenario.
What is the most correct way to stop a Thread that is blocking while waiting to receive a network message over UDP.
For example, say I have the following Thread:
public class ClientDiscoveryEngine extends Thread {
private final int PORT;
public ClientDiscoveryEngine(final int portNumber) {
PORT = portNumber;
}
#Override
public void run() {
try {
socket = new DatagramSocket(RECEIVE_PORT);
while (true) {
final byte[] data = new byte[256];
final DatagramPacket packet = new DatagramPacket(data, data.length);
socket.receive(packet);
}
} catch (SocketException e) {
// do stuff 1
} catch (IOException e) {
// do stuff 2
}
}
}
Now, would the more correct way be using the interrupt() method? For example adding the following method:
#Override
public void interrupt() {
super.interrupt();
// flip some state?
}
My only concern is, is socket.receive() not a non-interruptable blocking method? The one way that I have thought of would be to implement the interrupt method as above, in that method call socket.close() and then cater for it in the run method in the catch for the SocketException. Or maybe instead of while(true) use some state that gets flipped in the interrupt method. Is this the best way? Or is there a more elegant way?
Thanks
The receive method doesn't seem to be interruptible. You could close the socket: the javadoc says:
Any thread currently blocked in receive(java.net.DatagramPacket) upon
this socket will throw a SocketException
You could also use setSoTimeout to make the receive method block only for a small amount of time. After the method has returned, your thread can check if it has been interrupted, and retry to receive again for this small amount of time.
Read this answer Interrupting a thread that waits on a blocking action?
To stop a thread, you should not user neither interrupt nor stop in java. The best way, as you suggested by the end of your question, is to have the loop inside the main method controlled by a flag that you can rise as needed.
Here is an old link about this :
http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
Other ways of stopping a thread are deprecated and don't provide as much control as this one. Also, this may have changed a bit with executor services, I didn't have time to learn much about it yet.
Also, if you want to avoid your thread to be blocked in some IO state, waiting for a socket, you should give your socket a connection and reading time out (method setSoTimeout).
Regards,
Stéphane
This is one of the easier ones. If it's blocked on a UDP socket, send the socket a UDP message that instructs the receiving thread to 'stop'.
Rgds,
Martin
In Java thread, the 'run' method cannot throw a 'checked exception'. I came across this in the Core Java (vol 1) book. Can someone please explain the reasoning behind it?
Can someone please explain the reasoning behind it?
Yes, because any exception you throw in run method will be carefully ignored by JVM. Thus, throwing it there is probably a mistake (unless you have specific exception handler for the thread, see the docs about that). No reason to incite potentially erroneous behaviour.
Or, with an example.
class MyThread extends Thread {
public void run() {
throw new RuntimeException();
}
}
...
new MyThread().start();
// here thread dies silently with no visible effects at all
edit
Why can't the parent thread 'catch' the exception from the spawned 'child' thread?
#chaotic3quilibrium has already noted in his comment why not: because parent thread has likely moved on already.
new MyThread().start(); // launch thread and forget
// 1000 lines of code further...
i = i + 1; // would you like exception from child thread to be propagated here?
What would catch the exception and handle it? Let's assume that the run method could throw a checked exception. Then you could write code like this:
Thread myThread = new Thread(aRunnable);
try{
myThread.start();
}
catch(Exception e){
e.printStackTrace();
}
//do other stuff
BUT once you call myThread.start, the new thread is started in the background and the current thread continues and exits the try-catch and does other stuff. So if myThread did throw an exception later on, you can't catch it!
What you need to do is deal with the exception within the run method and then probably have a way of notifying another object that this thread failed.
Suppose thread A starts up thread B. Then thread B throws an exception. You might think it would be nice for thread A to catch it. But where? By the time thread B thows the exception, who knows what thread A is doing? To take a trivial example, suppose we have this code in thread A:
try
{
threadB=new PurgeAbandonedCarts();
threadB.start();
}
catch (NullPointerException panic)
{
... handle errors purging abandoned carts ...
}
try
{
processNewOrders();
}
catch (NullPointerException panic)
{
... handle problems in new orders ...
}
finally
{
... clean up ...
}
So we start up thread B to purge abandoned carts. Once it gets starte, we move on to processing new orders. Then thread B throws a null pointer exception. Should it be caught by the catch block associated with thread B, or the one associated with processing new orders?
If it goes to the new orders catch, it's likely that any code here has nothing to do with cleaning up problems with thread B. That can't be the right answer.
If you say the one associated with thread B, then that means that during the processing of new orders, control could suddenly be yanked out and sent back to try thread B catch block. But then what happenned to processing new orders? Do we just stop in the middle? Do we not even hit the finally block? And when we're done, do we then just keep executing and fall through to processing new orders again? Do we process orders twice? This can't be the right answer either.
Thus, there is nowhere to go if run throws an exception. The only logical thing to do is to have the run method catch any exceptions thrown itself, and handle them within the new thread.
throws declarations are part of the methods signature. To allow checked exceptions for Runnable#run, one had to declare them on the Runnable interface and had to try/catch everytime we start a thread.
Then again, we usually don't call the run method, we just implement it. We start() a Thread and then, somehow, the run method is called.
But the most obvious reason: When we start threads, we usually don't want to wait until the run method terminates just to catch exceptions like this:
try {
new Worker().start(); // now wait until run has finished
} catch (SomeThreadException oops) {
// handle checked exception
}
The reason is that exception is thrown back to the caller. Caller of run() method is not your code. It is the Thred itself. So even if run() throws exception the program cannot catch it.
You should put thread execution result to some class level variable and then read it from there. Or alternatively use new API: executors and interface Callable that declares method call() that returns future result of the thread execution.
The more obvious solution to the previous answers is that if you throw a checked exception, you are not correctly implementing run() as specified in the runnable interface.
It won't even compile:
run() in TestClass cannot implement run() in java.lang.Runnable;
overridden method does not throw java.lang.Exception