所以说你有一个java的网络程序,服务器一次为多个客户端服务,每个客户端访问他们的信息的方式只需输入他们的id。在服务器启动客户端的线程之前,您希望它确保客户端程序开始运行时用户键入的id尚未被当前正在运行的线程使用,并且它与特定的线程匹配模式(比如4位数)。我接近这个的方法是让服务器类在它执行任何操作之前为当前运行的线程的id声明并初始化一个arraylist,使用正则表达式来检查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语句中的正则表达式时以及当我告诉服务器在主方法中侦听对应于客户端套接字的端口时,服务器程序崩溃并给出空指针异常。我认为问题是我无法找到一种在线程启动之前获取客户端ID的方法,因为在我看来线程必须在用户输入其id之前启动,这会创建一个圆圈我必须正方形。任何人都可以帮我解决这个问题吗? PS:clientworker类接受一个套接字作为其构造函数的参数,并将其分配给已经声明的套接字引用,以防任何人混淆。
答案 0 :(得分: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()
正确同步,因为该集合由多个线程访问。