【Socket】三、Socket使用線程池支持多個線程同時訪問

一、使用循環不斷接受客戶端發送的消息

二、使用線程池優化訪問

三、使用Lambda優化線程池匿名內部類


【Socket】一、Socket概述

【Socket】二、UDP協議與TCP協議通訊示例

【Socket】三、Socket使用線程池支持多個線程同時訪問

一、使用循環不斷接受客戶端發送的消息

首先將第二節的TCPServer改造,使用while(true)讓服務器能夠一直接收客戶端發送的信息。

同時使用try-finally語法塊關閉連接。

public class TcpServer {

	public static void main(String[] args) throws IOException {

		System.out.println("socket服務器端啓動....");
		ServerSocket serverSocket = new ServerSocket(8088);
		try {
			while (true){
				//獲取客戶端對象
				Socket accept = serverSocket.accept();

				InputStream inputStream = accept.getInputStream();

				byte[] buf= new byte[1024];

				int len=inputStream.read(buf);

				String str =new String(buf,0,len);

				System.out.println("str:" + str);
			}
		} finally {
			serverSocket.close();
		}

	}
	
}

使用瀏覽器不斷訪問 http://127.0.0.1:8088/ 地址,控制檯會一直打印訪問信息。

缺點:只能支持一個客戶端訪問,無法支持多個同時訪問。

二、使用線程池優化訪問

注意這裏爲什麼不使用多線程而是線程池。因爲線程池可以放入緩存隊列。線程池其實就是多線程,提前提供了線程放入線程池,調用時供調用方使用,會出個專題專門講線程池,這裏只說使用。

在之前代碼基礎上,添加了線程池,此時代碼可供多個客戶端同時訪問,So easy!

public static void main(String[] args) throws IOException {
    System.out.println("socket服務器端啓動....");
	ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
	ServerSocket serverSocket = new ServerSocket(8088);
	try {
		while (true){
			//獲取客戶端對象
			Socket accept = serverSocket.accept();
			newCachedThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					try {

						InputStream inputStream = accept.getInputStream();
						byte[] buf= new byte[1024];
						int len=inputStream.read(buf);

						String str =new String(buf,0,len);
						System.out.println("str:" + str);

						//給瀏覽器反饋數據
						OutputStream outputStream = accept.getOutputStream();
						outputStream.write("this is my socket - TCP - Test".getBytes());

					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			});
		}
	} finally {
		serverSocket.close();
	}

}

三、使用Lambda優化線程池匿名內部類

這裏是個小插曲 以第二部的建立線程代碼爲例,咋們把建立過程使用lambda替換

注意lambda只存在於 JDK 1.8及以上!

二段代碼原文:

newCachedThreadPool.execute(new Runnable() {
	@Override
	public void run() {
		try {
			InputStream inputStream = accept.getInputStream();
			byte[] buf= new byte[1024];
			int len=inputStream.read(buf);
			String str =new String(buf,0,len);
			System.out.println("str:" + str);
			//給瀏覽器反饋數據
			OutputStream outputStream = accept.getOutputStream();
			outputStream.write("this is my socket - TCP - Test".getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
});

 使用lambda優化後的代碼

newCachedThreadPool.execute(new Thread(()->{
	try {
		InputStream inputStream = accept.getInputStream();
		byte[] buf= new byte[1024];
		int len=inputStream.read(buf);
		String str =new String(buf,0,len);
		System.out.println("str:" + str);
		//給瀏覽器反饋數據
		OutputStream outputStream = accept.getOutputStream();
		outputStream.write("this is my socket - TCP - Test".getBytes());
	} catch (IOException e) {
		e.printStackTrace();
	}
}));

可以看到代碼簡潔了不少。

然而更直觀點我們可以這樣

//Lambda
newCachedThreadPool.execute(new Thread(()->{
	System.out.println(1);
}));
//匿名內部類
newCachedThreadPool.execute(new Runnable() {
	@Override
	public void run() {
		System.out.println(1);
	}
});

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章