java - 无法从其他类(线程)的 Vector 获取元素

标签 java multithreading list vector

我有这个类(我的服务器启动类),在这里我为每个新客户端创建一个新线程。创建线程后,我将其添加到 vector (列表)中以跟踪 Activity 用户和连接,以便我可以向特定用户发送消息。但我无法从我的线程(下面的类)访问 vector 列表。你能解释一下我该怎么做吗?我有一个私有(private)列表和公共(public) setter 和 getter 方法,但我总是从 Vector 中获取大小 1。但我对其进行了测试,如果我与多个客户端连接,则会创建多个具有不同套接字的线程。如果我在服务器启动类中手动执行此操作,我可以将条目添加到 vector 中。

package securemessageserver;

public class SecureMessageServer {

private Vector<SecureMessageServerClientThread> userList = new Vector();
private SSLServerSocket sslserversocket;
int port = 9999;
private Boolean isRunning=true;
SSLSocket sslsocket;

private synchronized void loadCertificat(){
    try {
        URL url = this.getClass().getResource("/securemessageserver/keystore.jks");
        File file = new File(url.toURI());
        System.setProperty("javax.net.ssl.keyStore", "C:/keystore.jks");
        System.setProperty("javax.net.ssl.keyStorePassword", "Schelkan1994");
        //System.setProperty("javax.net.debug","all");
        System.out.println("Certifikat geladen");
    } catch (URISyntaxException ex) {
        Logger.getLogger(SecureMessageServer.class.getName()).log(Level.SEVERE, null, ex);;
        stopServer();
    }
}

private synchronized void createSocket(){
    try {
        SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();    
        sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(port);
        System.out.println("Socket erstellt mit "+port);
    } catch (IOException ex) {
        Logger.getLogger(SecureMessageServer.class.getName()).log(Level.SEVERE, null, ex);
        stopServer();
    }
}

private synchronized void startServer(SSLServerSocket sslserversocket){
    while(isRunning){
        try {
            System.out.println("Akzeptiere Verbindungen");
            sslsocket = (SSLSocket) sslserversocket.accept();
            SecureMessageServerClientThread client = new SecureMessageServerClientThread(sslsocket);
            startNewClient(client);
            userList.add(client);
        } catch (IOException ex) {
            Logger.getLogger(SecureMessageServer.class.getName()).log(Level.SEVERE, null, ex);
            stopServer();
        }
    }
}

public synchronized void startNewClient(SecureMessageServerClientThread th){
    new Thread(th).start();
}

public synchronized void stopServer(){
    isRunning=false;
}

public synchronized SSLServerSocket getServerSocket(){
    if(sslserversocket!=null){
        return this.sslserversocket;
    }
    return null;
}

public synchronized void addThreadToList(SecureMessageServerClientThread thread){
    userList.add(thread);
}

public synchronized void getAllThreadFromList(){
        System.out.println("Size: "+userList.size());
}

public synchronized String getUserName(){
    return userList.get(0).getUserOfThread();
}

public synchronized void deleteThreadFromList(SecureMessageServerClientThread thread){
    userList.remove(thread);
}

public synchronized void getUserNameOfAllThreads(){
    for(int i=0;userList.size()>i;i++){
        System.out.println(userList.get(i).getUserOfThread());
    }
}

public static void main(String[] args){
     SecureMessageServer server = new SecureMessageServer();
     server.loadCertificat();
     server.createSocket();
     server.startServer(server.sslserversocket);
}

}

如果新客户端连接以跟踪连接并执行输入和输出操作,则该类的另一个类(我的线程类)实例始终会创建。但我没有从另一个类中的 Vector 中获得正确的值......你看到我的错误了吗?感谢您的帮助

public class SecureMessageServerClientThread implements Runnable{

private SSLSocket socket;
private String userName;
boolean isRunning=true;

SecureMessageServer server = new SecureMessageServer();

public SecureMessageServerClientThread(SSLSocket socket){
    this.socket=socket;
}

private ObjectInputStream sInput;
private ObjectOutputStream sOutput;

@Override
public void run() {
    System.out.println("Client mit Socket is Running: "+socket);
    while(isRunning){
    try {
        sInput  = new ObjectInputStream(socket.getInputStream());
        SecureMessageServerClientMessage msg = (SecureMessageServerClientMessage) sInput.readObject();
        if(msg.getType()==0){
            System.out.println("All Threads:");
            server.getAllThreadFromList();
        }else if(msg.getType()==1){
            System.out.println(msg.getMessage());
        }else if(msg.getType()==2){
            Thread.sleep(1000);
            socket.close();
            this.stopThread();
        }else{
            System.out.println("Unbekannter Nachrichtentyp");
        }
    } catch (IOException ex) {
        Logger.getLogger(SecureMessageServerClientThread.class.getName()).log(Level.SEVERE, null, ex);
    }   catch (ClassNotFoundException ex) {
            Logger.getLogger(SecureMessageServerClientThread.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ex) {
            Logger.getLogger(SecureMessageServerClientThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

public void stopThread(){
    isRunning=false;


 //                 sOutput = new ObjectOutputStream(socket.getOutputStream());
}

public String getUserOfThread(){
    return this.userName;
}

public void getUserList(){
    server.getAllThreadFromList();
}

}

最佳答案

SecureMessageServerClientThread 中,您可以使用 SecureMessageServer server = new SecureMessageServer(); 创建一个新的 Server 实例。

这意味着当您在 getUserList 中调用 server.getAllThreadFromList() 时,您将从刚刚创建的没有客户端的服务器获取列表。

客户端线程应该将服务器实例作为参数:

SecureMessageServer server;

public SecureMessageServerClientThread(SSLSocket socket, SecureMessageServer server){
    this.socket=socket;
    this.server=server;
}

在服务器中,您应该将 this 传递给新的客户端实例:

SecureMessageServerClientThread client = new SecureMessageServerClientThread(sslsocket, this);

关于java - 无法从其他类(线程)的 Vector 获取元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31072022/

相关文章:

java - C:以编程方式查找 JVM 库文件位置

java - 在ArrayBlockingQueue中,为什么将final成员字段复制到局部final变量中?

Python 循环缺少结果

python - 访问格式类似于字典 Python 的列表中的信息

java - Spring boot - 在测试中注入(inject)的存储库映射为空

java - java中的数组和.substring

Java tcp套接字转换为udp

c# - 进度栏不适用于zipfile?程序似乎挂起时如何给出反馈

c# - 如何创建周期性任务

list - 在SWI prolog中实现nth1列表操作