程序在线程结束后挂起

时间:2013-12-17 14:39:30

标签: java multithreading

基本上我有一个ServerSocket监听器,在新的传入连接上程序执行一个线程来服务它,在线程完成后,程序不会继续 这是听众

client = listenSocket.accept();
        new HandleConnection(client);//HandleConnections extends thread and start 
                                         //method is called in the constructor                    
        counter++;
        System.out.println("Number of clients served : " + counter);

这是主题

public HandleConnection(Socket client) {
        this.client = client;
        this.start();
}
public void run() {

        try {
            in = new BufferedReader(new InputStreamReader(
                    client.getInputStream()));
            out = new PrintWriter(client.getOutputStream(), true);
            handler();
            System.out.println("Ending Thread !");

        } catch (IOException e) {
            //System.out.println("socket closed");
            e.printStackTrace();
        }

    }

消息“结束线程!”正常执行,但从不执行计数器++和以下println语句

2 个答案:

答案 0 :(得分:2)

  

消息“结束线程!”正常执行,但从不执行计数器++和以下println语句

因此,如果new HandleConnection(client);实际启动了一个新线程(您不应该在构造函数中执行,请参阅下文),那么应立即执行counter++并打印"Number of clients...消息。消息是否有可能出现在上面日志中的"Ending Thread!"消息?通常,启动实际线程需要一些时间,因此调用者将在输入run()方法之前继续执行。

有关您的代码的其他评论:

  • 正如@MarkoTopolnik所提到的,您需要在run()方法中关闭输入和输出流。 finally条款是必需的模式。
  • 由于围绕对象构造的Thread.start()竞争条件问题,您不应该在对象构造函数中调用Thread。请参阅:Why not to start a thread in the constructor? How to terminate?
  • 您应考虑实施Thread并执行以下操作,而不是延伸Runnable

    new Thread(new HandleConnection(client)).start();
    
  • 比自己管理线程更好的事情是为客户端处理程序使用ExecutorService线程池。请参阅this tutorial

答案 1 :(得分:0)

执行此操作的典型方法是执行以下操作:

    ServerSocket listener = new ServerSocket(3030); //Create a new socket to listen on

    try
    {
        //While we are running, if a client connects
        //accept the connect and increment the client ID
        while (true)
        {
            new udSocketServer(listener.accept()).start();
        }
    }
    finally //Gracefully close
    {
        listener.close(); //Close socket object
    }

然后,您可以在线程构造函数中调用共享变量'counter'。如果您需要更多,请告诉我,我会编辑。 但实际上,您需要更多代码才能回答。