簡體   English   中英

線程的run方法中的NullPointerException

[英]NullPointerException in Thread's run method

我真的很感謝我的程序的幫助。 它是具有多個客戶端的某種聊天服務器。 這是服務器代碼:

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”語句的行

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

我不相信嘗試時會發生這種情況。

打開IDE,打開調試,然后逐步進行,直到您看到發生了什么。 這是找出您錯過的最快方法。

您假設有一個對象沒問題。 找到它。

以下是如何正確執行此操作的示例:

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

很抱歉取消這樣一個老問題,但似乎這個問題沒有解決,因此我會從結尾提供一些建議。

我遇到了類似的問題,編譯器也不斷告訴我問題出在start()方法上。 但是,當我注釋掉線程部分並只在與UI相同的線程上運行代碼時,編譯器將我定向到問題的真正根源:線程內的代碼。

在確保代碼沒有給出錯誤之后,我用原始線程代碼將代碼括起來,然后停止提供NullPointerException錯誤。

希望這可以對某人有所幫助。

您的問題在於初始化靜態實例變量的順序。 嘗試做類似的事情:

...
private static Vector clients = null;
...
if (clients==null) {
    clients = new Vector(); // consider putting this in a synchronized block
}

在將客戶端添加到引導程序之前。

在JPanel中刪除重復的類聲明。

我試圖運行一個計時器線程,該線程在主應用程序窗口中更新了時鍾。

我已經使用Eclipse / WindowBuilder創建了JFrame,並遵循了有關如何制作計時器的教程。 我已將文本字段的聲明復制到類聲明中,以使其可用於整個類,但忘記了刪除小部件定義前面的類ID。 因此,它仍然初始化本地實例而不是全局實例。 因此,當我訪問全局變量時,它仍然為空。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM