1. Server
package com.mengnew.server;<br />import java.io.BufferedReader;<br />import java.io.IOException;<br />import java.io.InputStream;<br />import java.io.InputStreamReader;<br />import java.io.OutputStream;<br />import java.io.PrintWriter;<br />import java.net.ServerSocket;<br />import java.net.Socket;<br />import java.util.concurrent.ExecutorService;<br />import java.util.concurrent.Executors;<br />import org.apache.log4j.Logger;<br />import com.newbee.app.BugSqlMap;<br />import com.newbee.bean.Bugs;<br />import com.newbee.dao.BugsDAOImpl;<br />public class MultiThreadServer {<br />private static final Logger logger = Logger.getLogger(MultiThreadServer.class);<br />private ServerSocket serverSocket;<br />private ExecutorService executorService;// 線程池<br />private final int POOL_SIZE = 10;// 單個CPU線程池大小<br />public MultiThreadServer(int port) throws IOException {</p><p>serverSocket = new ServerSocket(port);<br />executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*POOL_SIZE);<br />logger.debug("伺服器啟動成功.");</p><p>}<br />public void service() {</p><p>while (true) {<br />Socket socket = null;<br />try {<br />// 接收客戶串連,只要客戶進行了串連,就會觸發accept();從而建立串連<br />socket = serverSocket.accept();<br />executorService.execute(new ServerHandler(socket));<br />} catch (Exception e) {<br />logger.debug(e);<br />}<br />}</p><p>}<br />public static void main(String[] args) throws IOException {</p><p>new MultiThreadServer(8821).service();</p><p>}<br />}<br />final class ServerHandler implements Runnable {<br />private static final Logger logger = Logger.getLogger(ServerHandler.class);<br />private Socket socket;<br />public ServerHandler(Socket socket) {<br />this.socket = socket;<br />}<br />private PrintWriter getWriter(Socket socket) throws IOException {<br />OutputStream socketOut = socket.getOutputStream();<br />return new PrintWriter(socketOut, true);<br />}<br />private BufferedReader getReader(Socket socket) throws IOException {<br />InputStream socketIn = socket.getInputStream();<br />InputStreamReader oi = new InputStreamReader(socketIn);<br />return new BufferedReader(oi);<br />}<br />public String echo(String msg) {<br />return "echo:" + msg;<br />}<br />public void run() {</p><p>PrintWriter streamWriter = null;<br />BufferedReader streamReader = null;</p><p>try {</p><p>logger.debug("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort());<br />streamWriter = getWriter(socket);<br />streamReader = getReader(socket);<br />String msg = null;<br />// streamReader.readLine()會block住線程,等待輸入<br />// socket.isClosed()檢測用戶端是否於已經關閉,避免出現死線程<br />while (!socket.isClosed() && (msg = streamReader.readLine()) != null) {<br />logger.debug(msg);</p><p>if (msg.indexOf("|")!=-1) {<br />String[] ms = msg.split("//|");<br />try {<br />Bugs bugs = new Bugs();<br />bugs.setRed(Integer.valueOf(ms[0]));<br />bugs.setGreen(Integer.valueOf(ms[1]));<br />bugs.setBlue(Integer.valueOf(ms[2]));</p><p>BugsDAOImpl dao = new BugsDAOImpl(BugSqlMap.getInstance());<br />dao.insertSelective(bugs);<br />} catch (Exception e) {<br />logger.debug(e);<br />}<br />}</p><p>streamWriter.println(echo(msg));<br />streamWriter.flush();<br />if (msg.equals("bye")) {// 結束對用戶端輸入資訊的等待,退出迴圈,關閉串連<br />break;<br />}<br />}<br />logger.info("socket closed.");<br />} catch (Exception e) {</p><p>logger.debug(e);</p><p>} finally {</p><p>try {<br />if (streamWriter != null) {<br />streamWriter.close();<br />}<br />if (streamReader != null) {<br />streamReader.close();<br />}<br />if (socket != null) {<br />socket.close();<br />}<br />} catch (Exception e) {<br />logger.debug(e);<br />}</p><p>}<br />}<br />}
1. Client
package com.mengnew.client;<br />import java.io.BufferedReader;<br />import java.io.IOException;<br />import java.io.InputStream;<br />import java.io.InputStreamReader;<br />import java.io.OutputStream;<br />import java.io.PrintWriter;<br />import java.net.Socket;<br />import java.util.concurrent.ExecutorService;<br />import java.util.concurrent.Executors;<br />import org.apache.log4j.Logger;</p><p>public class MultiThreadClient { </p><p>private static final int numTasks = 1000;<br />private static final String host="localhost";<br />private static final int port=8821;</p><p> public static void main(String[] args) { </p><p> ExecutorService exec = Executors.newCachedThreadPool();<br /> for (int i = 0; i < numTasks; i++) {<br /> exec.execute(new ClientHandler(i, host, port));<br /> }<br /> exec.shutdown();</p><p> } </p><p>}<br />final class ClientHandler implements Runnable { </p><p>private static final Logger logger = Logger.getLogger(ClientHandler.class);<br />private Socket socket = null;<br />private String host;<br />private int taskID;<br />private int port;</p><p>public ClientHandler(int taskID,String host, int port) {</p><p>this.taskID = taskID;<br />this.host = host;<br />this.port = port;</p><p>}</p><p> public void run() {</p><p> logger.debug("Task " + taskID + ":start"); </p><p> try {</p><p> // 串連伺服器<br /> socket = new Socket(host, port);</p><p> PrintWriter streamWriter = getWriter(socket);<br /> BufferedReader streamReader = getReader(socket); </p><p> // 發送資訊<br /> streamWriter.println("Process="+taskID);<br /> streamWriter.flush();<br /> logger.debug(streamReader.readLine());<br /> streamWriter.println("bye");// 關鍵語句,完成資訊提交,指示伺服器關閉串連<br /> streamWriter.flush();<br /> logger.debug(streamReader.readLine());</p><p> } catch (Exception e) {<br /> logger.debug(e);<br /> } </p><p> } </p><p>private PrintWriter getWriter(Socket socket) throws IOException {<br />OutputStream socketOut = socket.getOutputStream();<br />return new PrintWriter(socketOut, true);<br />}<br />private BufferedReader getReader(Socket socket) throws IOException {<br />InputStream socketIn = socket.getInputStream();<br />InputStreamReader oi = new InputStreamReader(socketIn);<br />return new BufferedReader(oi);<br />}<br />}
PS: 用戶端要有一個指示伺服器關閉串連的動作,否則會導致線程池資源耗盡