2

我正在实现一个非常基本的 API 以更好地控制 ServerSocket 和 Sockets,但是由于缺乏线程知识,我遇到了一个非常奇怪的问题,我无法解决。让我解释一下。

在我的类 SocketStreamReceiver 中,我使用辅助线程来侦听带有ServerSocket#accept(). 有 2 种方法:客户端可以使用 start() 和 stop() 来启动(创建线程并开始侦听accept())和停止(关闭 ServerSocket 并销毁线程)我的 SocketStreamReceiver。

你将如何实现 stop() 方法?请记住,可以在 doSomething() 内部调用 stop(),在 start() 启动的同一个辅助线程中。你可以改变任何你想要的东西:如果你愿意,你可以在线程内创建 ServerSocket,就在 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;
    }
}
4

1 回答 1

4

我会做

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

看来您甚至不需要运行标志。但是,我会在您的服务器接受代码中使用它来确定是否需要异常。即当运行 == false 时忽略所有异常。

我会变得running不稳定。

如果你可以从不同的线程运行它们,我会让 start()/stop() 同步。

于 2011-04-14T08:31:41.350 回答