1

我正在尝试创建一个连续线程,其中服务器从客户端接收/发送消息但是当我尝试检查下一个元素时它卡住了:

public void run()
{
    try
    {
        try
        {
            ArrayList<Socket> connections = parent.getConnections();
            in = new Scanner(socket.getInputStream());

            while(true)
            {
                if(in.hasNextLine()) // Gets stuck here
                {
                    String message = in.nextLine();
                    System.out.println("Client said " + message);
                }
            }
        }

        finally
        {
            socket.close();
        }
    }

    catch(Exception e)
    {
        e.printStackTrace();
    }

如何使循环不会卡在指定点

4

1 回答 1

1

假设您希望能够处理“行”,我可能会从以下内容开始:

public class SocketReader implements Runnable {

    private final InputStream stream;
    private final Queue<String> destination;
    private volatile boolean active = true;

    private SocketReader(InputStream stream, Queue<String> destination) {
        this.stream = stream;
        this.destination = destination;
    }

    public static SocketReader getReader(Socket toRead, Queue<String> destination) throws IOException {
        return new SocketReader(toRead.getInputStream(), destination);
    }

    public void shutdown() {
        active = false;
    }

    public void run() {
        while(active) {
            if (stream.hasNextLine() && active) {
                final String line = stream.nextLine;
                destination.add(line);
            }
        }
        try {
            stream.close();
        } catch (IOException e) {
            // Log somewhere
        }
    }
}

将它放到它自己的线程中(或者作为线程或执行程序池的一部分,真的),并且您已经使应用程序的其余部分与此代码无关。 期望在等待来自 的更新时阻塞stream.hasNextLine()BlockingQueue如果您不想主动轮询队列,但正在以其他方式处理更新,您甚至可以提供。

然后,您可以对输出执行以下操作:

public class QueuedPrinter implements Runnable {

    private final Queue<String> input;
    private final PrintStream destination;
    private volatile boolean active;

    public QueuedPrinter(Queue<String> input, PrintStream destination) {
        this.input = input;
        this.destination = destination;
    }

    public void shutdown() {
        active = false;
    }

    public void run() {
        while(active) {
            final String line = input.poll();
            if (line != null && active) {
                destination.println(line);
            }
        }
    }

}

请注意,我没有对此进行测试,您可能需要针对其他 Checked 异常稍作调整。您可能需要添加额外的错误检查代码(想到空处理)。此外,这不是完全线程安全的,但对于大多数用途来说可能“足够好”。

于 2012-06-05T16:28:53.237 回答