无法从其他类(Thread)中获取Vector中的元素

时间:2015-06-26 11:26:18

标签: java multithreading list vector

我有这个类(我的服务器启动类),在这里我为每个新客户创建一个新线程供他使用。 Thread创建之后,我将他添加到Vector(列表)以跟踪活动用户和连接,以便我可以向特定用户发送消息。但我无法从我的线程访问Vector-List(下面的类)。你能解释一下我怎么能这样做?我有一个私人列表和公共setter和getter方法,但我总是得到Vector的大小1。但我测试一下,如果我连接多个客户端,则会有多个具有不同套接字创建的线程。如果我在服务器启动类中使用manuel,我可以将Entrys添加到向量中。

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);
}

}

如果新客户端连接以跟踪连接并执行输入和输出操作,则总是创建此类的另一个类(My Thread Class)instanze。但是我没有从另一个类中的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();
}

}

2 个答案:

答案 0 :(得分:1)

SecureMessageServerClientThread中,您使用SecureMessageServer server = new SecureMessageServer();创建新的服务器实例。

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

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

SecureMessageServer server;

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

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

SecureMessageServerClientThread client = new SecureMessageServerClientThread(sslsocket, this);

答案 1 :(得分:0)

好吧,如果它是私人的,你显然无法从另一个班级访问。保护它并使两个类都在同一个包中。