如何在线程中正确使用类方法?

时间:2016-11-04 10:52:15

标签: java multithreading sockets

我正在研究这个问题:

//
// Application: Golf App Server
// Author: Andres Martinez
// Year: 2016
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package com.andress.golfappserver.listener;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import com.andress.golfappserver.beans.Client;
import com.andress.golfappserver.client.ClientHandler;
import com.andress.golfappserver.client.ClientStatus;

/**
 * This class has two main goals. First, start to listening the server in a certain port and
 * second, accepting incoming connections from clients. It runs as a Thread. The server
 * Administrator should provide the number of the port. When the Listener object is initialized
 * the ServerSocket will be listening to the port provided. To start to accept new connections
 * the Thread should be started. The Listener will create a new Client object every time when accepts
 * a new connection. The new Client will have the Socket accepted and a ClientStatus by default of
 * Connected. Then, a ClientHandler will be created with the Client as an argument.
 * The ClientController will be notified every time a new ClientHandler Thread is created.
 */
public class Listener implements Runnable {
  private final int port;
  private final ServerSocket serverSocket;

  /**
   * The Listener is instantiated and initialized with a port number
   * supplied by the Server Administrator. Then, the constructor
   * creates a new SeverSocket with this port ready to start to listen
   * for new connections.
   * @param port  Integer to identify port.
   */
  public Listener(final int port) {
    this.port = port;
    this.serverSocket = listen();
  }

  public int getPort() {
    return port;
  }

  public ServerSocket getServerSocket() {
    return serverSocket;
  }

  /**
   * Creates Client objects for accepted connections and spawns
   * a new ClientHandler for each of the new Client connections.
   */
  @Override
  public void run() {
    Client client = createClient(accept(this.serverSocket));
    ClientHandler clientHandler = new ClientHandler(client);
    //clientHandler.start();
  }

  /**
   * Binds the port provided by the Server Administrator to a new
   * ServerSocket.
   * @return  ServerSocket listening to the port provided.
   */
  private final ServerSocket listen() {
    try (ServerSocket serverSocket = new ServerSocket(port)) {
      return serverSocket;
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Starts to listen for connections to the port specified.
   * @param serverSocket  ServerSocket to listen for.
   * @return  Socket of the accepted connection.
   */
  private final Socket accept(final ServerSocket serverSocket) {
    try (Socket clientSocket = serverSocket.accept()) {
      return clientSocket;
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Creates a new Client Bean with ClientStatus by default
   * of Connected and the Socket of the new connection.
   * @param clientSocket  Socket for the new connection.
   * @return  Client object with ClientStatus of Connected by default.
   */
  private final Client createClient(final Socket clientSocket) {
    Client client = new Client();
    client.setSocket(clientSocket);
    client.setStatus(ClientStatus.CONNECTED);
    return client;
  }
}

我在使用套接字时出错,但我对此特定错误并不感兴趣。我想知道一个线程是否总是需要在run()方法中执行代码,或者有没有办法像我试图这样做?

错误:

Exception in thread "Thread-0" java.lang.RuntimeException: java.net.SocketException: Socket is closed
    at com.andress.golfappserver.listener.Listener.accept(Listener.java:85)
    at com.andress.golfappserver.listener.Listener.run(Listener.java:58)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.SocketException: Socket is closed
    at java.net.ServerSocket.accept(ServerSocket.java:509)
    at com.andress.golfappserver.listener.Listener.accept(Listener.java:82)
    ... 2 more

Process finished with exit code 0

1 个答案:

答案 0 :(得分:0)

  

线程总是需要在run()方法

中执行代码

是。这就是Java Thread的作用。

  

或者有没有办法像我试图这样做?

你实际上在run()中调用了一些方法,所以它应该完全有效。

更新

accept()方法中:

private final Socket accept(final ServerSocket serverSocket) {
    try (Socket clientSocket = serverSocket.accept()) {
        return clientSocket;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

您正在接受try-with-resources构造中的套接字。这意味着只要此方法结束,套接字就会关闭。我打赌那不是你想要做的。试试这个:

private final Socket accept(final ServerSocket serverSocket) {
    try {
        return serverSocket.accept();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}