前段時間做了一個面向Socket編程的項目,現在有時間和大家分享一下
首先是線程池:
Java通過Executors提供四種線程池,分別為:
newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
newFixedThreadPool 創建一個定長線程池,可控制線程最大並發數,超出的線程會在隊列中等待。
newScheduledThreadPool 創建一個定長線程池,支持定時及周期性任務執行。
newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行
這里我用的是newCachedThreadPool,因為要滿足多用戶短連接的需求,newFixedThreadPool可能也是一種好的選擇,因為它避免多次開啟關閉線程造成的資源浪費,但考慮到當沒用線程執行時,線程依然開啟,浪費資源,就沒有使用。newScheduledThreadPool和newSingleThreadExecutor不滿足該項目需求。由於項目既需要接收數據又需要發送數據,就開啟了兩個Socket端口,而socket.accept()方法阻塞式的,在開啟端口前就需要先通過 ExecutorService exc = Executors.newCachedThreadPool()方式創建線程池,在其中可以指定最大可創建線程數,默認值為1000.下面就是執行代碼:
//獲得當前正在執行的線程數
int count=((ThreadPoolExecutor)exec).getActiveCount();
//執行線程
exec.execute(new Task(client));
這里很重要的一點是Task這個類必須要實現Runnable接口,我這里面吧連接的通道傳到Task中,然后通過socket.getInputStream()得到字節流,為了方便處理把它轉化為字符流,new BufferedReader(new InputStreamReader(socket.getInputStream()));以及new PrintWriter(socket.getOutputStream(),true);
而且在實踐過程發現重要一點,通道的一端發送數據后立刻關閉通道,在另一端依然可以接受到數據。特意寫個測試代碼給大家實踐,包需要你們自己導入。
服務器端代碼:
1 public class Server { 2 static ServerSocket server; 3 4 public static void main(String[] args) { 5 6 try { 7 server = new ServerSocket(8100); 8 while (true) { 9 Socket socket = server.accept(); 10 PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); 11 pw.println("hi:客戶端"); 12 pw.close(); 13 socket.close(); 14 System.out.println("服務器已經關閉"); 15 } 16 } catch (IOException e) { 17 18 e.printStackTrace(); 19 } 20 21 } 22 23 }
客戶端代碼:
public class Cilent {
public static void main(String[] args) {
try {
String s = "";
Socket socket = new Socket("localhost", 8100);
Thread.sleep(2000);
BufferedReader bf = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
if ((s = bf.readLine()) != null) {
System.out.println(s);
}
socket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
研究后我想可能是因為
客戶端 服務端
out-----x------->in
in<--------------out
=========================================================================================================
今天更到這里,后面會介紹一下如何利用osm數據畫自己的地圖,以及用java實現基於硬盤的TPR樹。歡迎感興趣的小伙伴一起討論啊
