停止ServerSocket accept()循环线程 [英] Stopping a ServerSocket accept() loop thread
问题描述
我正在实现一个非常基本的API来更好地控制ServerSocket和Sockets,但是由于我缺乏线程知识,我处理的是一个非常奇怪的问题。让我解释一下。
I'm implementing a very basic API to have a better control over ServerSocket and Sockets, but I'm in a very weird problem that I cannot fix due to my lack of threads knowledge. Let me explain it.
在我的类SocketStreamReceiver中,我使用辅助线程来监听新的套接字 ServerSocket #accept()
。有两种方法:start()和stop()客户端可以用来启动(创建一个线程并开始用 accept()
监听)并停止(关闭ServerSocket)并且破坏了线程)我的SocketStreamReceiver。
In my class SocketStreamReceiver I use a secondary thread to listen for new sockets with ServerSocket#accept()
. There are 2 methods: start() and stop() that the client can use to start (creating a thread and begin listening with accept()
) and stop (closing the ServerSocket and destroying the thread) my SocketStreamReceiver.
你将如何实现stop()方法?请记住,stop()可以在里面调用doSomething(),在start()启动的同一个辅助线程中。你可以改变你想要的任何东西:你可以在线程内部创建ServerSocket,就在while(运行)之前。
How will you implement stop() method? Keep in mind that stop() can be called inside doSomething(), in the same secondary thread started by start(). You can change anything you want: you can create the ServerSocket inside the thread if you want, just before while(running).
public class SocketStreamReceiver{
...
private Thread thread;
private ServerSocket server;
private boolean running;
...
public void start () throws IOException{
if (thread != null) return;
server = new ServerSocket (port);
thread = new Thread (new Runnable (){
@Override
public void run (){
try{
while (running){
Socket socket = server.accept ();
doSomething (socket);
}
}catch (SocketException e){
...
}catch (IOException e){
...
}
}
}, "SocketStreamReceiver");
thread.start ();
}
public void stop () throws IOException{
if (thread == null) return;
//code...
thread = null;
}
}
谢谢。
编辑 - 解决方案:
public class SocketStreamReceiver{
private Thread thread;
private ServerSocket server;
private volatile boolean running;
...
public synchronized void start () throws IOException{
if (thread != null) throw new IllegalStateException ("The receiver is already started.");
server = new ServerSocket (port);
thread = new Thread (new Runnable (){
@Override
public void run (){
try{
running = true;
while (running){
doSomething (server.accept ());
...
}
}catch (SocketException e){
...
}catch (IOException e){
...
}
}
}, "SocketStreamReceiver");
thread.start ();
}
public synchronized void stop (){
if (thread == null) return;
running = false;
try{
if (server != null){
server.close ();
}
}catch (IOException e){}
thread = null;
}
}
推荐答案
我只会这样做
public void stop() {
running = false;
try{
if (server != null) server.close ();
} catch (IOException ignored){
}
}
看起来你甚至不需要运行标志。但是,我会在您的服务器接受代码中使用它来确定是否预期异常。即当运行== false时忽略所有异常。
It doesn't appear you even need the running flag. However I would use it in your server accept code to determine if an Exception is expected or not. i.e. when running == false ignore all exceptions.
我会使运行
volatile。
I would make running
volatile.
如果你可以从不同的线程运行这些,我会使start()/ stop()同步。
I would make start()/stop() synchronized if you can run these from different threads.
这篇关于停止ServerSocket accept()循环线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!