【Socket聊天室项目】while(true)循环效率问题

qq_36172692 2017-08-16 01:24:15
话不多说先上图


自己在写一个web项目要用到聊天功能,我在项目里面用到了一些while(true)样子的循环。每个客户端Socket我建了两个线程,一个用来监听客户端发来的信息,另一个用来监听别人发给客户端的信息(上图就是将别人存在本地的消息队列发送给客户端)。

这里用到了很多while(true)结构的循环,请问一下各位大佬,开启服务器后我发现开了200个客户端,服务器就会卡的shi一样,明显是while死循环太多造成的,有没有什么好的办法可以解决while循环多了效率会下降的问题?或者有什么办法可以代替while循环?

public class SocketListener {
/*
随Tomcat启动,准备100个端口,每个端口启动一个ServerSocket线程
*/
public static ArrayList<SoloServerSocketThread> SERVERS = new ArrayList<>();
public SocketListener() throws IOException {
for(int i=20001;i<=20100;i++){
SERVERS.add(new SoloServerSocketThread(i));
}
}


}


public class SoloClientSocketThread implements Runnable {
private Socket client;
private InputStream earphone;
private PrintStream microphone;
private Queue<String> speakQueue = new LinkedList<>();
private Queue<String> messageCache = new LinkedList<>();

private Long commitTime = System.currentTimeMillis();

/*
每一个人在一个时间点存在一个连接是打开中的状态,
*/
public Socket getClient() {
return client;
}

public SoloClientSocketThread(Socket client) throws IOException {
this.client = client;
earphone = client.getInputStream();
microphone = new PrintStream(client.getOutputStream());
new Thread(() -> {
while (!client.isClosed()) {
Long nowTime = System.currentTimeMillis();
if (nowTime > commitTime - 5 || nowTime < commitTime + 5) {//有没有更好的方法监听是否有消息传来?
String temp;
while ((temp = messageCache.poll()) != null) {
microphone.println(temp);
}
}
}
}).start();
}


public void destory() throws IOException {
earphone.close();
microphone.close();
client.close();
}

public boolean isDestoried() {
return client.isClosed();
}

public ArrayList<String> broadcast() {
//这个是发送方法,服务器主动读取客户端传来的消息。
ArrayList<String> list = new ArrayList<>();
String temp;
while ((temp = speakQueue.poll()) != null) {
list.add(temp);
}
return list.size() == 0 ? null : list;
}

public void record(String record) {
//这个是接收方法,外部找到对应对象之后调用则个方法可以将消息添加到队列,并给客户端发送过去
messageCache.add(record);
commitTime = System.currentTimeMillis() + 1000;
}

@Override
public void run() {
int b;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
while (!client.isClosed()) {
if ((b = earphone.read()) == '\n') {
speakQueue.add(baos.toString());
baos = new ByteArrayOutputStream();
} else {
baos.write(b);
}
}

} catch (IOException e) {
e.printStackTrace();
}
}
}


public class SoloServerSocketThread implements Runnable{
private Integer port;
private boolean isExit = false;
private ServerSocket server;

private static HashMap<String,SoloClientSocketThread> clients = new HashMap<>();
public void exit(){
isExit=true;
}

public static boolean drop(SoloClientSocketThread client){
return clients.remove(client.getClient().getInetAddress().getHostName(),client);
}

public static void drop(String clientHost){
clients.remove(clientHost);
}

public HashMap<String, SoloClientSocketThread> getClients() {
return clients;
}

public SoloServerSocketThread(Integer port) throws IOException {
this.port=port;
server = new ServerSocket(port);

}

@Override
public void run() {
try {
while (true){
Socket client = server.accept();
SoloClientSocketThread soloClient = new SoloClientSocketThread(client);
String clientHost;
if((clients.get(clientHost = soloClient.getClient().getInetAddress().getHostName()))==null) {
clients.put(clientHost,soloClient);
} else {
clients.replace(clientHost,soloClient);
}
new Thread(new SoloClientSocketThread(client)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}

public void setPort(Integer port) {
this.port=port;
}

public Integer getPort() {
return port;
}
}
...全文
315 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_34175173 2017-08-16
  • 打赏
  • 举报
回复
如果是的话可以用p2p模式解决
qq_34175173 2017-08-16
  • 打赏
  • 举报
回复
是不是因为线程开太多了,菜鸟不太懂,等大牛

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧