在程序的开发之中Java里面最小的处理单元就是线程,也就是说每一个线程可以进行IO的处理,在处理之中,该线程无法进行任何的其他操作。 . 多线程是不可能无限制进行创造的,所以需要去考虑堆线程进行有效的个数控制。如果产生的线程过多,那么直接的问题在于,处理性能降低 ,响应的速度变慢。 需要去区分操作系统的内核线程,以及用户线程的区别,所以最好与内核线程有直接联系,需要使用到固定线程池。
举一个生活中的例子,现在烧水,意味着你现在需要一直盯着水壶去看,一直看它已经烧为止,在这之中你什么都干不了。
public class BIOEchoServer {
public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(HostInfo.PORT) ;// 设置监听端口
System.out.println("服务器端已经启动,监听的端口为:" + HostInfo.PORT);
boolean flag = true ;
ExecutorService executorService = Executors.newFixedThreadPool(10) ;
while(flag) {
Socket client = serverSocket.accept() ;
executorService.submit(new EchoClientHandler(client)) ;
}
executorService.shutdown() ;
serverSocket.close() ;
}
private static class EchoClientHandler implements Runnable {
private Socket client ; // 每一个客户端都需要启动一个任务(task)来执行。
private Scanner scanner ;
private PrintStream out ;
private boolean flag = true ; // 循环标记
public EchoClientHandler(Socket client) {
this.client = client ; // 保存每一个客户端操作
try {
this.scanner = new Scanner(this.client.getInputStream()) ;
this.scanner.useDelimiter("\n") ; // 设置换行符
this.out = new PrintStream(this.client.getOutputStream()) ;
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(this.flag) {
if (this.scanner.hasNext()) { // 现在有数据进行输入
String val = this.scanner.next().trim() ; // 去掉多余的空格内容
System.out.println("{服务器端}" + val);
if("byebye".equalsIgnoreCase(val)) {
this.out.println("ByeByeByte...");
this.flag = false ;
} else {
out.println("【ECHO】" + val);
}
}
}
this.scanner.close();
this.out.close();
try {
this.client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class BIOEchoClient {
public static void main(String[] args) throws Exception {
Socket client = new Socket(HostInfo.HOST_NAME,HostInfo.PORT) ; // 定义连接的主机信息
Scanner scan = new Scanner(client.getInputStream()) ; // 获取服务器端的响应数据
scan.useDelimiter("\n") ;
PrintStream out = new PrintStream(client.getOutputStream()) ; // 向服务器端发送信息内容
boolean flag = true ; // 交互的标记
while(flag) {
String inputData = InputUtil.getString("请输入要发送的内容:").trim() ;
out.println(inputData); // 把数据发送到服务器端上
if(scan.hasNext()) {
String str = scan.next().trim() ;
System.out.println(str);
}
if ("byebye".equalsIgnoreCase(inputData)) {
flag = false ;
}
}
client.close();
}
}
public class InputUtil {
private static final BufferedReader KEYBOARD_INPUT = new BufferedReader(new InputStreamReader(System.in));
private InputUtil() {
}
/**
* 实现键盘数据的输入操作 ,可以返回的数据类型为String
*
* @param prompt 提示信息
* @return 输入的数据返回
*/
public static String getString(String prompt) {
boolean flag = true; // 数据接收标记
String str = null;
while (flag) {
System.out.print(prompt);
try {
str = KEYBOARD_INPUT.readLine(); // 读取一行数据
if (str == null || "".equals(str)) {
System.out.println("数据输入错误 ,该内容不允许为空:");
} else {
flag = false;
}
} catch (IOException e) {
System.out.println("数据输入错误 ,该内容不允许为空:");
}
}
return str;
}
}
测试一下: