0

因此,假设您有一个 Java 网络程序,其中服务器同时为多个客户端提供服务,每个客户端访问其信息的方式只需输入其 ID。在服务器为客户端启动线程之前,您希望它确保一旦客户端程序开始运行,用户输入的 id 尚未被当前正在运行的线程使用,并且它匹配特定的模式(比如 4 位数字)。我解决这个问题的方法是让服务器类在执行任何操作之前为当前正在运行的线程的 id 声明和初始化一个数组列表,使用正则表达式检查 id 是否为 4 位数长,如果是然后检查 id 是否在 arraylist 中,如果不是,则线程可以开始。代码如下图:

   while(true)
  {
     ClientWorker w;
     try
     {
        w = new ClientWorker(server.accept());
        String validid = w.accountnumber;
        if(validid.matches("\\d[4]"))
        {
             if(!currentusers.contains(validid))
             {
                currentusers.add(validid);
                Thread t = new Thread(w);
                t.start();
             }
             else
             {
                 System.out.println("Already in session");
             }
        }
        else
        {
            System.out.println("not a valid id");
        }
 }

问题是我的两个目标都没有实现,它只会导致以前工作的程序出错:无论我输入什么 id,客户都会继续前进并询问我想要进行哪些交易。然后,如果我尝试实际执行任何操作,则当我尝试匹配 if 语句中的正则表达式以及告诉服务器在 main 方法中侦听与客户端套接字对应的端口时,服务器程序会崩溃并给我空指针异常。我认为问题是我想不出在线程启动之前获取客户端 id 的方法,因为在我看来,线程必须在用户输入他们的 id 之前启动,这会创建一个圆圈我必须平方。谁能帮我解决这个问题?PS:

4

1 回答 1

0

算法应该是:

while (true)
    accept a new client
    start a thread to communicate with the client

线程应该这样做:

read the ID sent by the client
check if it's valid and add it to a set of IDs if not already present
if invalid or already present
    send an error message to the client
    stop running
else 
    continue the conversation with the client. 
    once the conversation ends, in a finally block, remove the ID from the set of IDs

您应该使用 HashSet 而不是 List,因为它在查找时要快得多 (O(1)),并且您应该确保方法checkIfIdPresentAndIfItDoesntThenAddTheId()removeId()正确同步,因为该集合由多个线程访问。

于 2012-12-08T23:20:18.857 回答