Thread的run方法中的NullPointerException

时间:2011-09-29 21:54:55

标签: java multithreading sockets nullpointerexception

我非常感谢帮助我的计划。它是某种具有多个客户端的聊天服务器。 这是服务器代码:

package com.server;

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


public class Server {
    public static int PORT;
    private ServerSocket server;
    private Socket socket;

    public Server(int port) throws IOException {
        PORT = port;
        server = new ServerSocket(PORT);
        System.out.println("server started");
        try {
            while (true) {
                socket = server.accept();
                try {
                    new ServeClient(socket);
                } catch (IOException e) {
                    socket.close();
                }
            }
        } finally {
            server.close();
        }

    }

    public static void main(String[] args) throws IOException {
        int port = Integer.parseInt(args[0]);
        Server server = new Server(port);
    }

}

我启动服务器然后创建一个客户端。服务器从套接字接收连接套接字 并创建一个ServeClient线程。 这是ServeClient代码:

package com.server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;

import com.gui.WindowManager;

public class ServeClient extends Thread {
    private final Socket socket;
    private BufferedReader in;
    private PrintWriter out;
    private String msg;
    public static final String ENDSTRING = "END";
    public static Vector clients = new Vector();

    public ServeClient(final Socket socket) throws IOException {
        this.socket = socket;
        System.out.println("socket " + socket);
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                socket.getOutputStream())), true);
        start();
    }

    public void run() {
        try {
            clients.add(this);
            while (true) {
                msg = in.readLine();
                if (msg == ENDSTRING)
                    break;
                broadcast(msg);
            }
            System.out.println("closing...");
        } catch (IOException e) {
            System.err.println("IO EXCEPTION");
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                System.err.println("SOCKET NOT CLOSED");
            }
        }
    }

    @SuppressWarnings("deprecation")
    public void broadcast(String msg) {
        synchronized (clients) {
            Enumeration<ServeClient> e = clients.elements();
            while (e.hasMoreElements()) {
                ServeClient serveClient = e.nextElement();
                try {
                    synchronized (serveClient.out) {
                        serveClient.out.println(msg);
                    }
                } catch (Exception eee) {
                    serveClient.stop();
                }
            }
        }
    }
}

当ServeClient调用run()方法时,我得到的是NullPointerException

server started
socket Socket[addr=/127.0.0.1,port=51438,localport=8888]
Exception in thread "Thread-0" java.lang.NullPointerException
    at com.server.ServeClient.run(ServeClient.java:33)

第33行是ServeClient run()方法中第一个“try”语句的行

4 个答案:

答案 0 :(得分:2)

com.server.ServeClient.run(ServeClient.java:33)

我不相信它会在尝试时发生。

打开IDE,打开调试,然后单步执行,直到看到发生了什么为止。这是弄清楚你错过了什么的最快方法。

有一个对象,你假设是好的,不是。找到它。

以下是如何正确执行此操作的示例:

http://www.kodejava.org/examples/216.html

答案 1 :(得分:1)

您的问题在于初始化静态实例变量的顺序。尝试做类似的事情:

...
private static Vector clients = null;
...
if (clients==null) {
    clients = new Vector(); // consider putting this in a synchronized block
}
在将客户端添加到向量之前

答案 2 :(得分:1)

很抱歉这个问题很糟糕,但似乎这个问题没有得到解决,所以我会从我的结尾给出一些意见。

我遇到了类似的问题,编译器也一直告诉我问题出在start()方法。但是,当我注释掉线程部分并且只是在与UI相同的线程上运行代码时,编译器将我引导到问题的真正来源:线程内的代码。

在确保代码没有出错之后,我用原始线程代码包含了代码,并且它停止给我NullPointerException错误。

希望这可以帮助一路上的人。

答案 3 :(得分:0)

删除JPanel中的重复类声明。

我试图运行一个更新主应用程序窗口中的时钟的计时器线程。

我用Eclipse / WindowBuilder创建了JFrame,并遵循了如何制作计时器的教程。我已将textfield的声明复制到类声明中以使其可用于整个类,但忘记删除窗口小部件定义前面的Class Id。所以它仍然初始化了本地实例而不是全局实例。因此,当我访问全局的时,它仍然是空的。