不使用线程池存在什么问题?
客户端与服务端的线程模型是N-N的关系
客户端并发越多,系统瘫痪的越快
发送端
package 线程池优化;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.security.spec.PSSParameterSpec;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
public class DClient {
public static void main(String[] args) throws Exception{
System.out.println("----发送端----");
//创建发送端对象
Socket sk=new Socket("127.0.0.1",8970);
OutputStream op=sk.getOutputStream();
PrintStream ps=new PrintStream(op);
Scanner sc=new Scanner(System.in);
while(true) {
System.out.println("请您输入内容(exit退出):");
String s=sc.nextLine();
if("exit".equals(s)) {
break;
}
ps.println(s);
ps.flush();//刷新管道
}
}
}
接收端
package 线程池优化;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.text.Utilities;
public class DServer {
private static ExecutorService es=new ThreadPoolExecutor(3, 5,3000,TimeUnit.MINUTES,new ArrayBlockingQueue<>(2),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) throws Exception{
System.out.println("--------接收端-------");
//注册端口
ServerSocket ss=new ServerSocket(8970);
while(true) {
Socket socket=ss.accept();
System.out.println(socket.getRemoteSocketAddress()+"上线了");
Runnable target= new WriteRunnable(socket);
es.execute(target);
}
}
}
任务对象
package 线程池优化;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class WriteRunnable implements Runnable {
private Socket socket;
public WriteRunnable(Socket socket) {
this.socket=socket;
}
@Override
public void run() {
try {
//获取输入管道
InputStream is=socket.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String information;
while((information=br.readLine())!=null) {
System.out.println("来自"+"ip"+socket.getInetAddress()+"端口:"+socket.getPort()+"信息内容为:" +information);
}
} catch (IOException e) {
System.out.println(socket.getRemoteSocketAddress()+"下线了");
}
}
}
因为要测试线程池就弄小了点,3个主线程,2个临时线程,2个等待队列,爆满直接抛异常
通过测试,可以发现线程池的好处,用上面的代码3个主线程,如果第四个客户端访问,就会进入等待队列,发送的消息也不会丢失, 等到等待队列慢了,临时线程开始工作,处理任务。在多的话就会抛出异常。如果前面的线程有结束,那么线程又会给等待队列中的线程执行
本次使用线程池的优势在哪里?
服务端可以复用线程池处理多个客户端,可以避免系统瘫痪
适合客户端通信时长较短的场景