Java Socket編程實(shí)例(三)- TCP服務(wù)端線程池
一、服務(wù)端回傳服務(wù)類(lèi):
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);
}
}
二、每個(gè)客戶(hù)端請(qǐng)求都新啟一個(gè)線程的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的線程次會(huì)有隊(duì)列、最大線程數(shù)、最小線程數(shù)和超時(shí)時(shí)間的概念)
1.線程池工具類(lèi):
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í)行器會(huì)在需要自行任務(wù)而線程池中沒(méi)有線程的時(shí)候來(lái)調(diào)用該程序。對(duì)于callable類(lèi)型的調(diào)用通過(guò)封裝以后轉(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)啟動(dòng),這里是異步的。
Future<T> future = executor.submit(task);
// System.out.println("Task aready in thread");
T t = null;
try {
/*
* 這里的操作是確認(rèn)任務(wù)是否已經(jīng)完成,有了這個(gè)操作以后
* 1)對(duì)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 */
}
}
以上就是本文的全部?jī)?nèi)容,查看更多Java的語(yǔ)法,大家可以關(guān)注:《Thinking in Java 中文手冊(cè)》、《JDK 1.7 參考手冊(cè)官方英文版》、《JDK 1.6 API java 中文參考手冊(cè)》、《JDK 1.5 API java 中文參考手冊(cè)》,也希望大家多多支持腳本之家。
相關(guān)文章
java開(kāi)發(fā)Activiti進(jìn)階篇流程實(shí)例詳解
這篇文章主要為大家介紹了java開(kāi)發(fā)Activiti進(jìn)階篇流程實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
SpringBoot如何訪問(wèn)html和js等靜態(tài)資源配置
這篇文章主要介紹了SpringBoot如何訪問(wèn)html和js等靜態(tài)資源配置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
spring-session簡(jiǎn)介及實(shí)現(xiàn)原理源碼分析
這篇文章主要介紹了spring-session簡(jiǎn)介及實(shí)現(xiàn)原理源碼分析,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
使用Jmeter進(jìn)行http接口測(cè)試的實(shí)踐
本文主要針對(duì)http接口進(jìn)行測(cè)試,使用Jmeter工具實(shí)現(xiàn)。文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
解析Java實(shí)現(xiàn)隨機(jī)驗(yàn)證碼功能的方法詳解
本篇文章是對(duì)Java實(shí)現(xiàn)隨機(jī)驗(yàn)證碼功能的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
GsonFormat快速生成JSon實(shí)體類(lèi)的實(shí)現(xiàn)
GsonFormat主要用于使用Gson庫(kù)將JSONObject格式的String?解析成實(shí)體,本文主要介紹了GsonFormat快速生成JSon實(shí)體類(lèi)的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-05-05
Java Swing中JList選擇事件監(jiān)聽(tīng)器ListSelectionListener用法示例
這篇文章主要介紹了Java Swing中JList選擇事件監(jiān)聽(tīng)器ListSelectionListener用法,結(jié)合具體實(shí)例形式分析了中JList選擇事件監(jiān)聽(tīng)器ListSelectionListener的功能、使用方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-11-11

