Java Socket編程實(shí)例(三)- TCP服務(wù)端線程池
一、服務(wù)端回傳服務(wù)類:
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.logging.Level; import java.util.logging.Logger; public class EchoProtocol implements Runnable { private static final int BUFSIZE = 32; // Size (in bytes) of I/O buffer private Socket clientSocket; // Socket connect to client private Logger logger; // Server logger public EchoProtocol(Socket clientSocket, Logger logger) { this.clientSocket = clientSocket; this.logger = logger; } public static void handleEchoClient(Socket clientSocket, Logger logger) { try { // Get the input and output I/O streams from socket InputStream in = clientSocket.getInputStream(); OutputStream out = clientSocket.getOutputStream(); int recvMsgSize; // Size of received message int totalBytesEchoed = 0; // Bytes received from client byte[] echoBuffer = new byte[BUFSIZE]; // Receive Buffer // Receive until client closes connection, indicated by -1 while ((recvMsgSize = in.read(echoBuffer)) != -1) { out.write(echoBuffer, 0, recvMsgSize); totalBytesEchoed += recvMsgSize; } logger.info("Client " + clientSocket.getRemoteSocketAddress() + ", echoed " + totalBytesEchoed + " bytes."); } catch (IOException ex) { logger.log(Level.WARNING, "Exception in echo protocol", ex); } finally { try { clientSocket.close(); } catch (IOException e) { } } } public void run() { handleEchoClient(this.clientSocket, this.logger); } }
二、每個客戶端請求都新啟一個線程的Tcp服務(wù)端:
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.logging.Logger; public class TCPEchoServerThread { public static void main(String[] args) throws IOException { // Create a server socket to accept client connection requests ServerSocket servSock = new ServerSocket(5500); Logger logger = Logger.getLogger("practical"); // Run forever, accepting and spawning a thread for each connection while (true) { Socket clntSock = servSock.accept(); // Block waiting for connection // Spawn thread to handle new connection Thread thread = new Thread(new EchoProtocol(clntSock, logger)); thread.start(); logger.info("Created and started Thread " + thread.getName()); } /* NOT REACHED */ } }
三、固定線程數(shù)的Tcp服務(wù)端:
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.logging.Level; import java.util.logging.Logger; public class TCPEchoServerPool { public static void main(String[] args) throws IOException { int threadPoolSize = 3; // Fixed ThreadPoolSize final ServerSocket servSock = new ServerSocket(5500); final Logger logger = Logger.getLogger("practical"); // Spawn a fixed number of threads to service clients for (int i = 0; i < threadPoolSize; i++) { Thread thread = new Thread() { public void run() { while (true) { try { Socket clntSock = servSock.accept(); // Wait for a connection EchoProtocol.handleEchoClient(clntSock, logger); // Handle it } catch (IOException ex) { logger.log(Level.WARNING, "Client accept failed", ex); } } } }; thread.start(); logger.info("Created and started Thread = " + thread.getName()); } } }
四、使用線程池(使用Spring的線程次會有隊(duì)列、最大線程數(shù)、最小線程數(shù)和超時時間的概念)
1.線程池工具類:
import java.util.concurrent.*; /** * 任務(wù)執(zhí)行者 * * @author Watson Xu * @since 1.0.0 <p>2013-6-8 上午10:33:09</p> */ public class ThreadPoolTaskExecutor { private ThreadPoolTaskExecutor() { } private static ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() { int count; /* 執(zhí)行器會在需要自行任務(wù)而線程池中沒有線程的時候來調(diào)用該程序。對于callable類型的調(diào)用通過封裝以后轉(zhuǎn)化為runnable */ public Thread newThread(Runnable r) { count++; Thread invokeThread = new Thread(r); invokeThread.setName("Courser Thread-" + count); invokeThread.setDaemon(false);// //???????????? return invokeThread; } }); public static void invoke(Runnable task, TimeUnit unit, long timeout) throws TimeoutException, RuntimeException { invoke(task, null, unit, timeout); } public static <T> T invoke(Runnable task, T result, TimeUnit unit, long timeout) throws TimeoutException, RuntimeException { Future<T> future = executor.submit(task, result); T t = null; try { t = future.get(timeout, unit); } catch (TimeoutException e) { throw new TimeoutException("Thread invoke timeout ..."); } catch (Exception e) { throw new RuntimeException(e); } return t; } public static <T> T invoke(Callable<T> task, TimeUnit unit, long timeout) throws TimeoutException, RuntimeException { // 這里將任務(wù)提交給執(zhí)行器,任務(wù)已經(jīng)啟動,這里是異步的。 Future<T> future = executor.submit(task); // System.out.println("Task aready in thread"); T t = null; try { /* * 這里的操作是確認(rèn)任務(wù)是否已經(jīng)完成,有了這個操作以后 * 1)對invoke()的調(diào)用線程變成了等待任務(wù)完成狀態(tài) * 2)主線程可以接收子線程的處理結(jié)果 */ t = future.get(timeout, unit); } catch (TimeoutException e) { throw new TimeoutException("Thread invoke timeout ..."); } catch (Exception e) { throw new RuntimeException(e); } return t; } }
2.具有伸縮性的Tcp服務(wù)端:
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import demo.callable.ThreadPoolTaskExecutor; public class TCPEchoServerExecutor { public static void main(String[] args) throws IOException { // Create a server socket to accept client connection requests ServerSocket servSock = new ServerSocket(5500); Logger logger = Logger.getLogger("practical"); // Run forever, accepting and spawning threads to service each connection while (true) { Socket clntSock = servSock.accept(); // Block waiting for connection //executorService.submit(new EchoProtocol(clntSock, logger)); try { ThreadPoolTaskExecutor.invoke(new EchoProtocol(clntSock, logger), TimeUnit.SECONDS, 3); } catch (Exception e) { } //service.execute(new TimelimitEchoProtocol(clntSock, logger)); } /* NOT REACHED */ } }
以上就是本文的全部內(nèi)容,查看更多Java的語法,大家可以關(guān)注:《Thinking in Java 中文手冊》、《JDK 1.7 參考手冊官方英文版》、《JDK 1.6 API java 中文參考手冊》、《JDK 1.5 API java 中文參考手冊》,也希望大家多多支持腳本之家。
相關(guān)文章
Spring @Async無法實(shí)現(xiàn)異步的解決方案
這篇文章主要介紹了Spring @Async無法實(shí)現(xiàn)異步的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10SpringBoot參數(shù)校驗(yàn)的最佳實(shí)戰(zhàn)教程
開發(fā)過程中,后臺的參數(shù)校驗(yàn)是必不可少的,下面這篇文章主要給大家介紹了關(guān)于SpringBoot參數(shù)校驗(yàn)的最佳實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-08-08詳解用Spring Boot Admin來監(jiān)控我們的微服務(wù)
這篇文章主要介紹了用Spring Boot Admin來監(jiān)控我們的微服務(wù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08使用@Validated 和 BindingResult 遇到的坑及解決
這篇文章主要介紹了使用@Validated 和 BindingResult 遇到的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10用Spring Native將SpringBoot程序轉(zhuǎn)換為GraalVM
這篇文章主要介紹了用Spring Native將SpringBoot程序轉(zhuǎn)換為GraalVM的方法,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot,感興趣的朋友可以了解下2021-04-04springboot serverEndpoint導(dǎo)致@resource注解不生效
在SpringBoot中,@Resource注解用于注入依賴,本文主要介紹了springboot serverEndpoint導(dǎo)致@resource注解不生效,具有一定的參考價值,感興趣的可以了解一下2023-12-12Spring Boot 定義系統(tǒng)啟動任務(wù)的多種方式
這篇文章主要介紹了Spring Boot 定義系統(tǒng)啟動任務(wù)的多種方式,看看你都會哪幾種 ,感興趣的朋友跟隨小編一起看看吧2019-04-04