为什么我会在 Socket 连接的 Java 线程中看到这个奇怪的输出? [英] Why am I seeing this weird output in Java threads in Socket connections?

查看:31
本文介绍了为什么我会在 Socket 连接的 Java 线程中看到这个奇怪的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有这个小代码:

public class MyCounterClass {
    private static int counter = 0;
    synchronized public static int getCounter(){
        return counter++;
    }
}

这是服务器:

public class MyServer implements Runnable{

    public static void go() throws IOException {

        System.out.println("MyServer: Go called...");
        ServerSocket serverSocket = new ServerSocket(5000);
        while(true){
            Socket socket = serverSocket.accept();
            System.out.println(time() + "MyServer: Connection accepted!");
            OutputStream outputStream = socket.getOutputStream();
            System.out.println(time() + "MyServer: socket.getOutputStream");
            PrintWriter printWriter = new PrintWriter(outputStream);
            System.out.println(time() + "MyServer: New PrintWriter object created!");
            printWriter.write(time() + "Hello from my socket!");
            System.out.println(time() + "MyServer: printwriter.write method called..");
            printWriter.flush();
            System.out.println(time() + "MyServer: Flushed!");
            printWriter.close();
            System.out.println(time() + "MyServer: printWriter closed...");
        }
    }

    public static String time(){
        return String.valueOf(MyCounterClass.getCounter()) + " ";
    }

    @Override
    public void run() {
        try {
            go();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这是客户:

public class MyClient implements Runnable {

    public static void go() throws IOException {
        Socket socket = new Socket("localhost",5000);
        System.out.println(time() + "My Client: Connection established...");
        InputStream inputStream = socket.getInputStream();
        System.out.println(time() + "MyClient: socket.getInputStream...");
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        System.out.println(time() + "MyClient: BufferedReader object created...");
        System.out.println(time() + bufferedReader.readLine());
    }

    public static String time(){
        return String.valueOf(MyCounterClass.getCounter()) + " ";
    }

    @Override
    public void run() {
        try {
            go();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

以及我如何运行程序:

public class TestClass {
    public static void main(String[] args) throws IOException, InterruptedException {
        Thread server = new Thread(new MyServer());
        server.start();
        Thread.sleep(750);
        Thread client = new Thread(new MyClient());
        client.start();
    }
}

和输出:

MyServer: Go called...
0 My Client: Connection established...
1 MyServer: Connection accepted!
2 MyClient: socket.getInputStream...
3 MyServer: socket.getOutputStream
4 MyClient: BufferedReader object created...
6 MyServer: New PrintWriter object created!
8 MyServer: printwriter.write method called..
9 MyServer: Flushed!
10 MyServer: printWriter closed...
5 7 Hello from my socket!

我的问题是,最后一行如何得到5 和 7"?

My question is, how can the last line get "5 and 7"?

推荐答案

  • 5 -> 客户端收到消息的时间"
  • 7 -> 服务器发送消息的时间"
  • 由于客户端和服务器是独立的线程,所以不会按顺序输出时间.

    since the client and server are independent threads, they will not output times in order.

    主要的混淆来自于这一行:

    the primary confusion comes because of this line:

    System.out.println(time() + bufferedReader.readLine());
    

    似乎 println 正在回到过去".然而,发生的事情是 time() 方法在时间5"时被调用.但是,由于普通的 Java 套接字是阻塞的,所以 bufferedReader.readLine() 调用会挂起,直到数据从服务器实际可用为止,这在服务器发送数据之后才会发生(当然).然后,一旦 readLine 方法返回, println 调用实际上就完成了.

    It seems like the println is going "back in time". what is happening, however, is that the time() method is called way back at time "5". but, since normal java sockets are blocking, the bufferedReader.readLine() call hangs until the data is actually available from the server, which doesn't happen until after it is sent by the server (of course). then, once the readLine method returns, the println call actually completes.

    如果您想看到更合乎逻辑"的进展,请将最后一行更改为:

    if you want to see a more "logical" progression, change the last client line to:

    String result = bufferedReader.readLine();
    System.out.println(time() + result);
    

    这将延迟客户端的最后一次 time() 调用,直到之后实际收到响应.

    that will delay the client's last time() call until after the response is actually received.

    这篇关于为什么我会在 Socket 连接的 Java 线程中看到这个奇怪的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆