题目
想要服务器不停止,能接收很多客户上传的图片?我们知道是使用循环加多线程的方案来解决,但是如果频繁的创建和销毁线程,是非常浪费系统资源的,那应该怎么办呢?
解决方案
采用线程池,来管理线程
代码实战
客户端代码
package com.heima; import java.io.*; import java.net.Socket; public class Client { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1",10000); //读取本地文件中的数据,并写到服务器中 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("G:\\wjkwk\\clientdir\\123.jpg")); BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); byte[] bytes = new byte[1024]; int len; while ((len = bis.read(bytes)) != -1){ bos.write(bytes,0,len); } //往服务器写结束标记 socket.shutdownOutput(); //接收服务器返回的数据 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = br.readLine(); System.out.println(line); socket.close(); } }
服务端代码
package com.heima; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class Server { public static void main(String[] args) throws IOException { ThreadPoolExecutor pool = new ThreadPoolExecutor( 3, 16, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2),// Executors.defaultThreadFactory(),//线程工厂,让线程池如何创建线程对象 new ThreadPoolExecutor.AbortPolicy()//阻塞队列 ); ServerSocket serverSocket = new ServerSocket(10000); while (true){ //等待客户端来连接 Socket socket = serverSocket.accept(); //开启一个线程 //一个用户就对应服务端的一条线程 // new Thread(new MyRunnable(socket)).start(); //使用线程池 pool.submit(new MyRunnable(socket)); } } }
package com.heima; import java.io.*; import java.net.Socket; import java.util.UUID; public class MyRunnable implements Runnable { Socket socket; public MyRunnable(Socket socket){ this.socket = socket; } @Override public void run() { try { //读取客户端上传的文件并保存到本地 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); String name = UUID.randomUUID().toString().replace("-", ""); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("G:\\wjkwk\\serverdir\\"+name+".jpg")); int len; byte[] bytes = new byte[1024]; while ((len = bis.read(bytes)) != -1){ bos.write(bytes,0,len); } //回写数据 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bw.write("上传成功"); bw.newLine(); bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { //释放资源 try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }