1. Server
package com.mengnew.server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.log4j.Logger; import com.newbee.app.BugSqlMap; import com.newbee.bean.Bugs; import com.newbee.dao.BugsDAOImpl; public class MultiThreadServer { private static final Logger logger = Logger.getLogger(MultiThreadServer.class); private ServerSocket serverSocket; private ExecutorService executorService;// 线程池 private final int POOL_SIZE = 10;// 单个CPU线程池大小 public MultiThreadServer(int port) throws IOException { serverSocket = new ServerSocket(port); executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*POOL_SIZE); logger.debug("服务器启动成功."); } public void service() { while (true) { Socket socket = null; try { // 接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接 socket = serverSocket.accept(); executorService.execute(new ServerHandler(socket)); } catch (Exception e) { logger.debug(e); } } } public static void main(String[] args) throws IOException { new MultiThreadServer(8821).service(); } } final class ServerHandler implements Runnable { private static final Logger logger = Logger.getLogger(ServerHandler.class); private Socket socket; public ServerHandler(Socket socket) { this.socket = socket; } private PrintWriter getWriter(Socket socket) throws IOException { OutputStream socketOut = socket.getOutputStream(); return new PrintWriter(socketOut, true); } private BufferedReader getReader(Socket socket) throws IOException { InputStream socketIn = socket.getInputStream(); InputStreamReader oi = new InputStreamReader(socketIn); return new BufferedReader(oi); } public String echo(String msg) { return "echo:" + msg; } public void run() { PrintWriter streamWriter = null; BufferedReader streamReader = null; try { logger.debug("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort()); streamWriter = getWriter(socket); streamReader = getReader(socket); String msg = null; // streamReader.readLine()会block住线程,等待输入 // socket.isClosed()检测客户端是否于已经关闭,避免出现死线程 while (!socket.isClosed() && (msg = streamReader.readLine()) != null) { logger.debug(msg); if (msg.indexOf("|")!=-1) { String[] ms = msg.split("//|"); try { Bugs bugs = new Bugs(); bugs.setRed(Integer.valueOf(ms[0])); bugs.setGreen(Integer.valueOf(ms[1])); bugs.setBlue(Integer.valueOf(ms[2])); BugsDAOImpl dao = new BugsDAOImpl(BugSqlMap.getInstance()); dao.insertSelective(bugs); } catch (Exception e) { logger.debug(e); } } streamWriter.println(echo(msg)); streamWriter.flush(); if (msg.equals("bye")) { // 结束对客户端输入信息的等待,退出循环,关闭连接 break; } } logger.info("socket closed."); } catch (Exception e) { logger.debug(e); } finally { try { if (streamWriter != null) { streamWriter.close(); } if (streamReader != null) { streamReader.close(); } if (socket != null) { socket.close(); } } catch (Exception e) { logger.debug(e); } } } }
1. Client
package com.mengnew.client; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.log4j.Logger; public class MultiThreadClient { private static final int numTasks = 1000; private static final String host="localhost"; private static final int port=8821; public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); for (int i = 0; i < numTasks; i++) { exec.execute(new ClientHandler(i, host, port)); } exec.shutdown(); } } final class ClientHandler implements Runnable { private static final Logger logger = Logger.getLogger(ClientHandler.class); private Socket socket = null; private String host; private int taskID; private int port; public ClientHandler(int taskID,String host, int port) { this.taskID = taskID; this.host = host; this.port = port; } public void run() { logger.debug("Task " + taskID + ":start"); try { // 连接服务器 socket = new Socket(host, port); PrintWriter streamWriter = getWriter(socket); BufferedReader streamReader = getReader(socket); // 发送信息 streamWriter.println("Process="+taskID); streamWriter.flush(); logger.debug(streamReader.readLine()); streamWriter.println("bye"); // 关键语句,完成信息提交,指示服务器关闭连接 streamWriter.flush(); logger.debug(streamReader.readLine()); } catch (Exception e) { logger.debug(e); } } private PrintWriter getWriter(Socket socket) throws IOException { OutputStream socketOut = socket.getOutputStream(); return new PrintWriter(socketOut, true); } private BufferedReader getReader(Socket socket) throws IOException { InputStream socketIn = socket.getInputStream(); InputStreamReader oi = new InputStreamReader(socketIn); return new BufferedReader(oi); } }
PS: 客户端要有一个指示服务器关闭连接的动作,否则会导致线程池资源耗尽