JAVA服务器端Socket线程池
- 格式:docx
- 大小:19.48 KB
- 文档页数:7
⼀个简单的Socket通信Demo服务器端Demo:Server.java(服务器端运⾏主程序,直接运⾏):package cn.wjs;import .InetAddress;import .ServerSocket;import .Socket;public class Server {private static final int port = 9999;private static final int backlog = 100;private static final String bindAddr = "127.0.0.1";public static void main(String[] args) throws Exception {System.out.println("正在启动Socket服务器");ServerSocket server = new ServerSocket(9998, 100, InetAddress.getByName("127.0.0.1"));System.out.println("启动完成\n正在监听客户端连接");while (true) {Socket socket = server.accept();System.out.println("产⽣了⼀个新的会话,来⾃:" + socket.getInetAddress() + "\n=================================="); new ServerMessageReceiver(socket).start();new ServerMessageSender(socket).start();System.out.println("服务器端已启动");}}}ServerMessageReceiver.java:package cn.wjs;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import .Socket;public class ServerMessageReceiver extends Thread{private Socket socket;public ServerMessageReceiver(Socket socket){this.socket = socket;}public void run() {try {BufferedReader reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream(), "UTF-8"));String content = null;while (true) {if (this.socket.isClosed()) {System.out.println("Socket已经关闭");reader.close();this.socket.close();break;}content = reader.readLine();if (content.equals("bye")) {System.out.println("对⽅请求关闭连接,⽆法继续进⾏聊天");reader.close();this.socket.close();break;}System.out.println("【对⽅】" + content + "\n");}reader.close();this.socket.close();}catch (UnsupportedEncodingException e){e.printStackTrace();}catch (IOException e) {e.printStackTrace();}}}ServerMessageSender.java:package cn.wjs;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.UnsupportedEncodingException;import .Socket;public class ServerMessageSender extends Thread{private Socket socket;public ServerMessageSender(Socket socket){this.socket = socket;}public void run() {try {BufferedWriter outwriter = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream(), "UTF-8")); BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));String msg = null;while (true) {msg = inputReader.readLine();if (msg.toLowerCase().equals("exit")) {System.exit(0);}if (this.socket.isClosed()) {System.out.println("Socket已经关闭");outwriter.close();inputReader.close();this.socket.close();break;}outwriter.write(msg);outwriter.newLine();outwriter.flush();}}catch (UnsupportedEncodingException e){e.printStackTrace();}catch (IOException e) {e.printStackTrace();}}}ClientDemo:Client.java(客户端主程序,直接运⾏):package cn.wjs;import java.io.IOException;import .InetAddress;import .Socket;import .UnknownHostException;public class Client{private static final int port = 9999;private static final String bindAddr = "127.0.0.1";public static void main(String[] args){System.out.println("正在连接Socket服务器");try {Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9998);System.out.println("已连接\n================");new ClientMessageSender(socket).start();new ClientMessageReceiver(socket).start();System.out.println("已启动");}catch (UnknownHostException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}}}ClientMessageReceiver.java:package cn.wjs;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import .Socket;public class ClientMessageReceiver extends Thread{private Socket socket;public ClientMessageReceiver(Socket socket){this.socket = socket;}public void run(){try {BufferedReader reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream(), "UTF-8")); String content = null;while (true) {if (this.socket.isClosed()) {System.out.println("Socket已经关闭");reader.close();this.socket.close();break;}content = reader.readLine();if (content.equals("bye")) {System.out.println("对⽅请求关闭连接,⽆法继续进⾏聊天");reader.close();this.socket.close();break;}System.out.println("【对⽅】" + content + "\n");}}catch (UnsupportedEncodingException e){e.printStackTrace();}catch (IOException e) {e.printStackTrace();}}}ClientMessageSender.java:package cn.wjs;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.UnsupportedEncodingException;import .Socket;public class ClientMessageSender extends Thread{private Socket socket;public ClientMessageSender(Socket socket){this.socket = socket;}public void run(){try {BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream(), "UTF-8"));BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String msg = null;while (true) {msg = reader.readLine();if (msg.toLowerCase().equals("exit")) {System.exit(0);}if (this.socket.isClosed()) {System.out.println("Socket已经关闭");writer.close();this.socket.close();break;}writer.write(msg);writer.newLine();writer.flush();}}catch (UnsupportedEncodingException e){e.printStackTrace();}catch (IOException e) {e.printStackTrace();}}}通过elicpse导出jar包直接运⾏,服务器端导出jar设置main.class为Server.java,客户端导出jar设置main.class为Client.java------这是传统的TCP/BIO模式.如果多个客户端向服务器发送请求,通常采⽤连接池的⽅式来维护,这和数据库的连接池⼀个道理。
一、什么是ServerSocket?在计算机网络编程中,ServerSocket是一种用于监听客户端连接请求的服务器端套接字。
通过创建ServerSocket对象,程序可以在指定的端口上监听客户端的连接,并接受客户端发起的连接请求。
一旦建立连接,程序可以通过ServerSocket接受客户端的请求,并与客户端进行数据交换。
二、ServerSocket的基本用法1. 创建ServerSocket对象要创建ServerSocket对象,可以使用以下代码:```javaServerSocket serverSocket = new ServerSocket(8888);```这段代码创建了一个ServerSocket对象,并让其在8888端口上监听客户端的连接请求。
2. 监听客户端连接要监听客户端的连接请求,可以使用以下代码:```javaSocket clientSocket = serverSocket.accept();```这段代码会阻塞程序,直到有客户端发起连接请求。
一旦有客户端连接进来,accept()方法会返回一个Socket对象,程序可以通过这个Socket对象与客户端进行通信。
3. 数据交换一旦建立连接,程序可以通过Socket对象与客户端进行数据交换。
可以使用InputStream和OutputStream来读取客户端发送的数据或向客户端发送数据。
```javaInputStream inputStream = clientSocket.getInputStream(); OutputStream outputStream = clientSocket.getOutputStream(); // 读取客户端发送的数据// 向客户端发送数据```三、ServerSocket的实际应用ServerSocket在实际的网络编程中发挥着重要的作用。
一个基于Socket通信的服务器程序通常会使用ServerSocket来监听客户端的连接请求,并在客户端连接时创建一个新的线程来处理与客户端的通信。
java线程池的使用例子随着计算机技术的不断发展,我们的软件系统越来越复杂,程序的性能要求也越来越高。
在这样的背景下,线程池成为了一种非常重要的工具。
Java线程池是Java提供的一种简单易用的线程管理工具,可以帮助我们更好地管理程序中的线程,提高程序的性能和稳定性。
本文将通过一个实际的例子来介绍Java线程池的使用方法和注意事项。
希望读者可以通过本文的学习,更好地掌握Java线程池的使用技巧。
一、什么是线程池?在介绍Java线程池之前,我们需要先了解什么是线程池。
线程池是一种管理线程的机制,可以帮助我们更好地管理程序中的线程,提高程序的性能和稳定性。
线程池的主要作用是为每个任务分配一个线程,当任务完成后,线程会被回收并可供下一个任务使用。
这样,线程的创建和销毁的开销就可以得到控制,避免了频繁创建和销毁线程所带来的性能损失。
二、Java线程池的使用方法1. 创建线程池Java线程池的创建方式非常简单,只需要使用ThreadPoolExecutor类即可。
以下是一个简单的线程池创建代码: ```ExecutorService executor =Executors.newFixedThreadPool(5);```这个代码创建了一个固定大小为5的线程池。
如果需要创建其他类型的线程池,可以使用其他的静态工厂方法,如newCachedThreadPool()、newSingleThreadExecutor()等。
2. 提交任务创建好线程池之后,我们就可以向线程池提交任务了。
以下是一个简单的线程池提交任务代码:```executor.submit(new Runnable() {@Overridepublic void run() {// 执行任务}});```这个代码提交了一个Runnable类型的任务,线程池会自动为其分配一个线程执行。
如果需要提交其他类型的任务,可以使用Callable、Future等接口。
6、java5线程池之固定⼤⼩线程池newFixedThreadPoolJDK⽂档说明:创建⼀个可重⽤固定线程数的线程池,以共享的⽆界队列⽅式来运⾏这些线程。
在任意点,在⼤多数 nThreads 线程会处于处理任务的活动状态。
如果在所有线程处于活动状态时提交附加任务,则在有可⽤线程之前,附加任务将在队列中等待。
如果创建⽅法:java.util.concurrent.Executors.newFixedThreadPool(int nThreads)orjava.util.concurrent.Executors.newFixedThreadPool(int nThreads, ThreadFactory threadFactory)调⽤上⾯2个⽅法得到的对象为:ExecutorServiceJDK⾃带的例⼦:下⾯给出了⼀个⽹络服务的简单结构,这⾥线程池中的线程作为传⼊的请求。
它使⽤了预先配置的Executors.newFixedThreadPool(int)⼯⼚⽅法:class NetworkService implements Runnable {private final ServerSocket serverSocket;private final ExecutorService pool;public NetworkService(int port, int poolSize) throws IOException {serverSocket = new ServerSocket(port);pool = Executors.newFixedThreadPool(poolSize);}public void run() { // run the servicetry {for (;;) {pool.execute(new Handler(serverSocket.accept()));}} catch (IOException ex) {pool.shutdown();}}}class Handler implements Runnable {private final Socket socket;Handler(Socket socket) { this.socket = socket; }public void run() {// read and service request on socket}}主要的⽅法:boolean awaitTermination(long timeout, TimeUnit unit)请求关闭、发⽣超时或者当前线程中断,⽆论哪⼀个⾸先发⽣之后,都将导致阻塞,直到所有任务完成执⾏。
Java线程池使⽤和常⽤参数多线程问题:1、java中为什么要使⽤多线程使⽤多线程,可以把⼀些⼤任务分解成多个⼩任务来执⾏,多个⼩任务之间互不影像,同时进⾏,这样,充分利⽤了cpu资源。
2、java中简单的实现多线程的⽅式继承Thread类,重写run⽅法;12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28class MyTread extends Thread{public void run() { System.out.println(Thread.currentThread().getName());}}实现Runable接⼝,实现run⽅法;class MyRunnable implements Runnable{ public void run() { System.out.println(Thread.currentThread().getName()); }}class ThreadTest { public static void main(String[] args) { MyTread thread = new Mythread(); thread.start(); //开启⼀个线程 MyRunnable myRunnable = new MyRunnable(); Thread runnable = new Thread(myRunnable); runnable.start(); //开启⼀个线程 }}3、java线程的状态创建:当new了⼀个线程,并没有调⽤start之前,线程处于创建状态;就绪:当调⽤了start之后,线程处于就绪状态,这是,线程调度程序还没有设置执⾏当前线程;运⾏:线程调度程序执⾏到线程时,当前线程从就绪状态转成运⾏状态,开始执⾏run⽅法⾥边的代码;阻塞:线程在运⾏的时候,被暂停执⾏(通常等待某项资源就绪后在执⾏,sleep、wait可以导致线程阻塞),这是该线程处于阻塞状态;死亡:当⼀个线程执⾏完run⽅法⾥边的代码或调⽤了stop⽅法后,该线程结束运⾏4、为什么要引⼊线程池当我们需要的并发执⾏线程数量很多时,且每个线程执⾏很短的时间就结束了,这样,我们频繁的创建、销毁线程就⼤⼤降低了⼯作效率(创建和销毁线程需要时间、资源)。
java 获取线程池状态方法线程池是Java多线程编程中常用的工具,它可以管理和重用线程,提高程序的性能和可靠性。
然而,了解线程池的状态是开发人员必备的技能。
本文将详细介绍Java中获取线程池状态的方法,帮助读者全面了解线程池的运行情况,提供有指导意义的指导。
要获取线程池的状态,首先需要创建一个线程池对象。
我们通常使用`ThreadPoolExecutor`类来创建线程池,该类提供了丰富的方法来操作和管理线程池。
以下是创建线程池的示例代码:```javaExecutorService executor =Executors.newFixedThreadPool(5);```在这个示例中,我们创建了一个固定大小的线程池,最多可以同时执行5个任务。
接下来,我们将介绍几种常用的方法来获取线程池的状态。
1. 获取线程池的活动线程数要获取线程池中当前活动线程的数量,我们可以使用`getActiveCount()`方法。
这个数值表示当前正在执行任务的线程数量。
示例代码如下:```javaint activeThreads = ((ThreadPoolExecutor)executor).getActiveCount();System.out.println("当前活动线程数:" + activeThreads);```2. 获取线程池的任务完成数线程池中的任务可以通过`submit()`方法提交到线程池中执行。
要获取线程池中已经完成的任务数量,我们可以使用`getCompletedTaskCount()`方法。
示例代码如下:```javalong completedTasks = ((ThreadPoolExecutor) executor).getCompletedTaskCount();System.out.println("已完成任务数:" + completedTasks);```3. 获取线程池的任务总数线程池的任务总数包括正在执行的任务和已经完成的任务。
java创建线程池的三种方法一、使用ThreadPoolExecutor类创建线程池ThreadPoolExecutor是Java提供的一个线程池实现类,通过它可以方便地创建一个线程池。
ThreadPoolExecutor提供了丰富的参数和方法来满足不同的需求。
创建ThreadPoolExecutor的方式一般有两种,一种是直接创建ThreadPoolExecutor的实例,另一种是通过Executors工厂类提供的静态方法来创建。
1. 直接创建ThreadPoolExecutor实例可以通过构造函数来创建ThreadPoolExecutor实例,构造函数的参数包括核心线程数、最大线程数、线程空闲时间、任务队列等。
示例代码如下:```javaThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, // 核心线程数maximumPoolSize, // 最大线程数keepAliveTime, // 线程空闲时间TimeUnit.SECONDS, // 时间单位workQueue // 任务队列);```2. 使用Executors工厂类创建ThreadPoolExecutor实例Executors工厂类提供了一些静态方法来创建ThreadPoolExecutor 实例,比如newFixedThreadPool、newCachedThreadPool等。
示例代码如下:```javaExecutorService executor = Executors.newFixedThreadPool(nThreads); // 创建固定大小的线程池ExecutorService executor = Executors.newCachedThreadPool(); // 创建可缓存的线程池```二、使用ScheduledThreadPoolExecutor类创建定时线程池ScheduledThreadPoolExecutor是ThreadPoolExecutor的子类,它专门用于创建定时线程池。
完整的后端开发流程-深⼊浅出Java线程池:使⽤篇⼿动步骤⾛⼀种完整的后端开发流程服务端1、将远程仓库的jar包拷贝到本地仓库2、将项⽬代码拷贝到本地并建⽴路径能够执⾏编译3、编译打包项⽬(package)⾄项⽬下,项⽬跑起来后进⾏本地测试4、版本稳定后,上测试环境上测试环境1、将远程仓库的jar包拷贝到测试环境2、将本地的项⽬代码上传到测试环境 pom能建⽴路径执⾏mvn脚本进⾏编译打包3、编译打包项⽬(package)⾄项⽬下,项⽬跑起来后进⾏测试4、版本在测试环境稳定后,install⾄本地仓库,在上传⾄远程仓库5、不推荐嫌⿇烦直接上传本地jar包的⽅式,因为这样⽆法发现由于环境造成的错误⽽且传输速度没有直接编译的快客户端联调1、将远程仓库的jar包(包括刚刚上传的服务端jar) 拷贝到本地仓库2、将项⽬代码拷贝到本地并建⽴路径能够执⾏编译3、编译打包项⽬(package)⾄项⽬下,项⽬跑起来后进⾏本地测试4、项⽬注册⾄RPC服务中来访问跑在测试环境的服务端项⽬5、版本稳定后,上测试环境联调。
团队的技术栈,基于这个背景再展开后⾯将提到的⼏个问题,将会有更深刻的体会。
控制层基于SpringMvc,数据持久层基于JdbcTemplate⾃⼰封装了⼀套类MyBatis的Dao框架,视图层基于Velocity模板技术,其余组件基于SpringCloud全家桶。
问题1某应⽤发布以后开始报数据库连接池不够⽤异常,⽇志如下:1com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 500, maxActive 500, creating 0 很明显这是数据库连接池满了,当时处于业务低峰期,所以很显然并不是由于流量突发造成的,另⼀种可能性是长事务导致,⼀般是事务中掺杂了外部⽹络调⽤,最终跟业务负责⼈⼀起排除了长事务的可能性。
java socket 实现原理
Java的Socket是一种用于网络通信的编程接口。
它基于
TCP/IP协议,通过在不同计算机之间建立连接,实现了进程
之间的通信。
在Java中,Socket通信包括客户端和服务器端两个角色。
客
户端通过创建一个Socket对象来发起连接,服务器端通过创
建一个ServerSocket对象来监听连接请求。
具体实现原理如下:
1. 客户端创建一个Socket对象,指定服务器的IP地址和端口号。
Socket对象会封装了TCP/IP协议的相关信息,如IP地址
和端口号等。
2. 客户端通过Socket对象的connect()方法发起连接请求,向
服务器发送一个特定格式的数据包。
3. 服务器端创建一个ServerSocket对象,绑定到指定的IP地
址和端口号上。
4. 服务器端通过ServerSocket对象的accept()方法监听来自客
户端的连接请求。
当有连接请求到达时,accept()方法会返回
一个新的Socket对象,用于和客户端进行通信。
5. 客户端和服务器端通过各自的Socket对象进行数据的收发。
客户端通过输出流向服务器发送数据,服务器通过输入流接收
客户端发送的数据;服务器通过输出流向客户端发送数据,客户端通过输入流接收服务器发送的数据。
6. 当通信完成后,可以通过关闭Socket对象来结束连接。
通过以上步骤,客户端和服务器端能够通过Socket对象实现双向的数据传输。
Socket提供了简单、灵活和高效的网络通信方式,广泛应用于各种应用场景中。
Java中的Socket⽤法转发链接:(1)Java中的Socket⽤法Java中的Socket分为普通的Socket和NioSocket。
(2)普通Socket⽤法创建ServerSocket。
ServerSocket的构造⽅法有5个,其中最⽅便的是ServerSocket(int port),只需要⼀个port就可以了。
Java中的⽹络通信时通过Socket实现的,Socket分为ServerSocket和Socket两⼤类,ServerSocket⽤于服务器端,可以通过accept⽅法监听请求,监听请求后返回Socket,Socket⽤于完成具体数据传输,客户端也可以使⽤Socket发起请求并传输数据。
ServerSocket的使⽤可以分为三步:调⽤创建出来的ServerSocket的accept⽅法进⾏监听。
accept⽅法是阻塞⽅法,也就是说调⽤accept⽅法后程序会停下来等待连接请求,在接受请求之前程序将不会继续执⾏,当接收到请求后accept⽅法返回⼀个Socket。
使⽤accept⽅法返回的Socket与客户端进⾏通信 如下代码,我们在服务器端创建ServerSocket,并调⽤accept⽅法监听Client的请求,收到请求后返回⼀个Socket。
public class Server {public static void main(String[] args) {// TODO Auto-generated method stubtry {//创建⼀个ServerSocket监听8080端⼝ServerSocket server = new ServerSocket(8080);//等待请求Socket socket = server.accept();//接受请求后使⽤Socket进⾏通信,创建BufferedReader⽤于读取数据BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));String line = is.readLine();System.out.println("received frome client:" + line);//创建PrintWriter,⽤于发送数据PrintWriter pw = new PrintWriter(socket.getOutputStream());pw.println("this data is from server");pw.flush();//关闭资源pw.close();is.close();socket.close();server.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}} 然后我们再看看客户端的Socket代码,Socket的使⽤也是⼀样,⾸先创建⼀个Socket,Socket的构造⽅法⾮常多,这⾥⽤的是Socket(String host, int port),把⽬标主机的地址和端⼝号传⼊即可(本实验代码中服务器和Client代码没有在同⼀台机器上,服务器的IP地址:192.168.6.42,所以如果读者在实验过程中ServerSocket和Client在同⼀主机下,那么Client中的IP地址需要更改为:127.0.0.1,Socket 创建的过程就会跟服务器端建⽴连接,创建完Socket后,再创建Writer和Reader来传输数据,数据传输完成后释放资源关闭连接。
JAVA服务器端Socket线程池import java.util.Vector;import .*;import java.io.*;public class ThreadPool {public static final int MAX_THREADS = 100;public static final int MAX_SPARE_THREADS = 50;public static final int MIN_SPARE_THREADS = 10;public static final int WORK_WAIT_TIMEOUT = 60 * 1000;protected Vector pool; //存放空闲线程protected MonitorRunnable monitor; //A monitor thread that monitors the pool for idel thre ads.protected int maxThreads; //Max number of threads that you can open in the pool.protected int minSpareThreads; //Min number of idel threads that you can leave in the po ol.protected int maxSpareThreads; //Max number of idel threads that you can leave in the p ool.protected int currentThreadCount; //Number of threads in the pool.protected int currentThreadsBusy; //Number of busy threads in the pool.protected boolean stopThePool; //Flag that the pool should terminate all the threads and stop./*** Construct*/public ThreadPool() {maxThreads = MAX_THREADS;maxSpareThreads = MAX_SPARE_THREADS;minSpareThreads = MIN_SPARE_THREADS;currentThreadCount = 0;currentThreadsBusy = 0;stopThePool = false;}/*** 启动线程池*/public synchronized void start() {adjustLimits(); //调整最大和最小线程数及最大和最小多余线程数.openThreads(minSpareThreads); //打开初始线程monitor = new MonitorRunnable(this); //Runnable对象实例 //A monitor thread that monitors the pool for idel threads.}public void setMaxThreads(int maxThreads) {this.maxThreads = maxThreads;}public int getMaxThreads() {return maxThreads;}public void setMinSpareThreads(int minSpareThreads) {this.minSpareThreads = minSpareThreads;}public int getMinSpareThreads() {return minSpareThreads;}public void setMaxSpareThreads(int maxSpareThreads) {this.maxSpareThreads = maxSpareThreads;}public int getMaxSpareThreads() {return maxSpareThreads;}/*** 线程池管理方法.* 当空闲队列线程中没有空闲线程时,则增加处理(空闲)线程数量.* 如果线程数量已达到最大线程数,则新的连接进行等待.* 当请求到来,且有空闲线程时调用处理线程进行具体业务处理.* @param r ThreadPoolRunnable*/public void runIt(Socket cs) { //r 为task //有任务进入时调用if (null == cs) {throw new NullPointerException();}if (0 == currentThreadCount || stopThePool) {throw new IllegalStateException();}ControlRunnable c = null; //任务处理实例.synchronized (this) {if (currentThreadsBusy == currentThreadCount) { //如果工作线程和当前线程数相等,说明没有空闲线程.if (currentThreadCount < maxThreads) { //如果当前线程数还没有达到最大线程数.int toOpen = currentThreadCount + minSpareThreads; //再增加minSpareThreads个线程量.openThreads(toOpen); //打开线程新增空闲线程. //currentThreadCount数量增加}else { //如果当前数量达到了最大线程数.while (currentThreadsBusy == currentThreadCount) { //当工作线程和当前线程数相等,说明没有空闲线程.try {this.wait(); //连接线程进行等待.}catch (InterruptedException e) {}if (0 == currentThreadCount || stopThePool) {throw new IllegalStateException();}}}}c = (ControlRunnable) stElement(); //在有空闲线程的情况下,从空闲线程队列中取出最后一个线程.pool.removeElement(c); //从空闲队列中删除最后一个线程,用于处理其他事件.currentThreadsBusy++; //对处理事件的线程数加1}System.out.println("系统调用一个Sokcet线程");c.runIt(cs); //调用具体业务方法,告诉其有数据请求要处理,唤醒等待中的线程.}/*** 关闭线程池*/public synchronized void shutdown() {if (!stopThePool) { //如果线程池没有关闭,(线程池关闭标识为假)stopThePool = true;monitor.terminate(); //关闭监视线程monitor = null;for (int i = 0; i < (currentThreadCount - currentThreadsBusy); i++) { //关闭空闲线程队列try {( (ControlRunnable) (pool.elementAt(i))).terminate();}catch (Throwable t) {}}currentThreadsBusy = currentThreadCount = 0;pool = null;notifyAll(); //唤醒所有在等待的线程.}}/*** 当线程大于最大多余线程时关闭多余的线程.*/protected synchronized void checkSpareControllers() {if (stopThePool) { //如果连接池没有关闭.return;}if ( (currentThreadCount - currentThreadsBusy) > maxSpareThreads) { //如果空闲的线程数大于多余的最大线程数量.int toFree = currentThreadCount - currentThreadsBusy - maxSpareThreads; //得出多余的线程数量for (int i = 0; i < toFree; i++) { //关闭删除空闲线程,从Vector中删除ControlRunnable c = (ControlRunnable) pool.firstElement();pool.removeElement(c);c.terminate(); //让删除的线程结束currentThreadCount--; //处理线程队列减少一个}}}/*** 当线程处理完成后重新放到空闲线程队列中.* @param c ControlRunnable*/protected synchronized void returnController(ControlRunnable c) {if (0 == currentThreadCount || stopThePool) { //如果线程池关闭或当前连接线程数量为0c.terminate(); //关闭当前线程.return;}currentThreadsBusy--; //处理线程队列的数量减少一个pool.addElement(c); //空闲线程队列中增加一个notifyAll(); //唤醒可能在等待连接的线程.}/*** 当一个处理线程出现异常时,要重新开启一个空闭线程.,并唤醒在等待空闲线程的线程.ThreadPool的runIt中等待的线程.*/protected synchronized void notifyThreadEnd() {currentThreadsBusy--; //因从线程是在处理数据时出现异常,所处理线程队列的数量要减一个.currentThreadCount--; //因出现异常的线程关闭了.所开户线程的数量要减少一个.notifyAll(); //唤醒等待连接的阻塞线程.openThreads(minSpareThreads); //重新打开minSpareThreads个线程.如currentThreadCount的数量大于minSpareThreads,则还是不开启新线程.}/*** 调整各种线程队列数量*/protected void adjustLimits() {if (maxThreads <= 0) { //如果最大线程数小于0maxThreads = MAX_THREADS; //设置最大线程数为100}if (maxSpareThreads >= maxThreads) { //如果最大多余线程数大于最大线程数.maxSpareThreads = maxThreads; //设置最大多余线程数为最大线程数.}if (maxSpareThreads <= 0) { //如果最大多余线程数小于0if (1 == maxThreads) {maxSpareThreads = 1; //如最大线程数为1的情况下,设置最大多余线程数为1.}else {maxSpareThreads = maxThreads / 2; //设置最大多余线程数为最大线程数的一半.}}if (minSpareThreads > maxSpareThreads) { //如果最小多余线程大于最大多余线程数minSpareThreads = maxSpareThreads; //设置最小多余线程数为最大多余线程数.}if (minSpareThreads <= 0) { //如果最小多余线程数小于0if (1 == maxSpareThreads) {minSpareThreads = 1; //如最大线程数为1的情况下,则设置最小多余线程数为1.}else {minSpareThreads = maxSpareThreads / 2; //否则设置最小多余线程数为最大多余线程数的一半.}}}/*** 打开指定数量的空闲线程队列* @param toOpen int*/protected void openThreads(int toOpen) { //toOpen=minSpareThreadsif (toOpen > maxThreads) {toOpen = maxThreads;}if (0 == currentThreadCount) { //如果当前线程池中的线程数量为0pool = new Vector(toOpen); //创建一个有minSpareThreads数量的Vector}//因第二次增加时对第一次增加的线程不能重复增加.所要从currentThreadCount开始.for (int i = currentThreadCount; i < toOpen; i++) { //先增加minSparethreads数量的线程.pool.addElement(new ControlRunnable(this)); //Runnable实例对象,可用于创建线程}currentThreadCount = toOpen;}/*** 监视线程,用于监听当前空闲线程是否大于最大多余线程数量,如存在则关闭多余的空闲线程.*/class MonitorRunnableimplements Runnable {ThreadPool p;Thread t;boolean shouldTerminate;/*** construct* @param p ThreadPool*/MonitorRunnable(ThreadPool p) {shouldT erminate = false;this.p = p;t = new Thread(this);t.start();}public void run() {while (true) {try {synchronized (this) {this.wait(WORK_WAIT_TIMEOUT);}if (shouldTerminate) { //如果结束break;}p.checkSpareControllers(); //检查是否有多余线程.}catch (Throwable t) {t.printStackTrace();}}}public void stop() {this.terminate();}public synchronized void terminate() { shouldT erminate = true;this.notifyAll();}}}。