Reputation: 3168
I have a Swing form with a button, which is when clicked starts SocketServer
for listening to incoming requests in a separate thread. Following is structure of classes I have.
MainForm
: This is my main class which launches Swing Form. It has two buttons, "start server" and "stop buttons".MySocketServer
: This class is where SocketServer
object exists, it has methods startServer()
and stopServer()
.Following is Start button's Click Event Body.
t = new Thread(new Runnable() //Object t is created globally in this main class.
{
public void run()
{
myss = new MySocketServer(); //Object myss has similar accessibility as t.
myss.startServer();
}
});
t.start();
And Following is Stop Button's Click Event Body
myss.stopServer();
if(t.isAlive());
System.out.println("Thread is still alive!!");
Though I can toggle SockeServer "start" and "stop" as my times I want, but I realize that everytime I start the server, new thread gets created and it remains active even though server is stopped using MySocketServer
's method.
I can use stop()
of Thread
and stop the thread execution but since it is depreciated and I have studied that threads get ended once their run()
method has executed completely, but I have startServer()
method separated so that it can handle connected clients separately.
Please note that startServer()
has While-Listen loop, so essentially run()
method of thread is in infinite state of execution, until I explicitly call stopServer()
and halt the loop.
what can be done here?
Upvotes: 0
Views: 858
Reputation: 719229
Firstly, you are right to not try to use Thread.stop()
. It is potentially dangerous.
So what should you do?
One possibility might to be to write your server thread like this:
....
ServerSocket ss = new ServerSocket(...);
try {
while (keepGoing) {
Socket s = ss.accept(...);
try {
// do stuff
} finally {
// close socket
}
}
} finally {
// close the server socket
}
and have stopServer
clear the keepGoing
flag. But the problem is that the stop typically will come while the thread is blocked in the accept
call, and there's nothing to unblock it.
Another possibility might be to call Thread.interrupt()
on the thread. That causes some things to unblock, and throw an exception, but I don't think it will unblock the accept()
call though. (However, this is still better than setting a flag if the "do stuff" part needs interrupting.)
The real solution (I think) is to close the ServerSocket
. This will cause the ss.accept()
call to unblock and throw an exception, which you need to handle in the server thread.
Upvotes: 1
Reputation: 2939
You shouldn't use stop(). Take a look at this http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html The solution with infinite loop and start/stop flags is straightforward but leads to ineffective using of CPU time. The better way is to use wait/notify approach. The way you operate with MySocketServer gives me feeling that you have other infinite loop inside the startServer(). That's why you have to stop it. It would be better to wrap this loop into it's own thread internally and make start/stop methods operate with this thread state in wait/notify manner. Forgot to mention, as your GUI runs in its own thread you can't escape start/stop flag inside the MySocketServer because using wait() in GUI thread will make it hanged.
Upvotes: 0
Reputation: 5892
In your MySocketServer class in the while loop you need a flag which will test if it should keep running or not.
In your newly added shutdown method set the flag which the loop in the thread will test. Once the loop breaks and run() returns the thread will end.
Upvotes: 0