I have got a main thread and within that thread I start a new thread. (the child thread). That child thread opens a server socket and starts listening for a connection. I want that thread to stop its execution and close whatever it has initialized (like the Socket) when the main thread gets a message from outside (from where it gets the the message is not the concern). How should I stop the thread and close all the connections is what I want.
Should I use a shared variable? so that when the main thread receives the message it should modify it and the child thread should continually check for the changes in that shared variable?
How should I implement it? Some useful links may help or a sample code ?
What I have tried is as follows: in the main thread I have declared a variable
flag=0;
when the main thread receives the message, it sets
flag = 1 ;
and the thread listens for the change as follows:
void ()run{
while(true){
if(flag==1){
break;
}
sock1 = Ssocket.accept();
}
But the above code is not at all working. How should I do it?
Answers
The proper way to interrupt a thread is via the interruption mechanism. In your main thread, when you want to stop the child thread, you call:
childTread.interrupt();
and in the child thread, you do something like:
public void run() {
try {
while (!Thread.currentThread.isInterrupted) {
sock1 = Ssocket.accept();
//rest of the code here
}
} catch (InterruptedException e) {
Thread.currentThread.interrupt(); //good practice
}
//cleanup code here: close sockets etc.
}
Note that Ssocket.accept isn't interruptible, so if you want to stop it from waiting, you will have to close it from outside, to force it to throw an IOException.
Child thread
You should make a new function here, f.e:
public void setFlag(int i)
{
flag = i;
}
Parent Thread
Whenever you want to kill/stop listening/... in the child thread, make a call to:
childThread.setFlag(1);
If you don't need the child Thread to be anonymous, create a ChildThread class:
public ChildThread implements Runnable
{
private int flag = 0;
public ChildThread()
{ }
public void setFlag(int i)
{
flag = i;
}
public void run()
{
//your code
}
....
}
If you are using a flag to signal a thread to stop, make sure read/write access is synchronized. For example:
public synchronized void cancel ()
{
stop = true;
}
protected synchronized boolean cancelRequested ()
{
return stop;
}
Extend Runnable with your own implementation:
public class StoppableRunnable extends Runnable {
}
Code your class so that you can stop the execution of the Runnable, you will find a good example of how to do this here How to properly stop the Thread in Java. Make sure you look at the first two answers.
In your equivalent of the terminate() function, do all your cleanup

