题目
想要服务器不停止,能接收很多客户上传的图片?我们知道是使用循环加多线程的方案来解决,但是如果频繁的创建和销毁线程,是非常浪费系统资源的,那应该怎么办呢?
解决方案
采用线程池,来管理线程
代码实战
客户端代码
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();
}
}
}
}