Stopping a ServerSocket accept() loop thread

喜你入骨 提交于 2019-12-22 00:24:26

问题


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.

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.

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;
    }
}

Thanks.

EDIT - Solution:

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;
    }
}

回答1:


I would just do

public void stop() {
    running = false;
    try{
        if (server != null) server.close ();
    } catch (IOException ignored){
    }
}

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.

I would make running volatile.

I would make start()/stop() synchronized if you can run these from different threads.



来源:https://stackoverflow.com/questions/5660390/stopping-a-serversocket-accept-loop-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!