本举例
![](/icons/9327chengxu.gif)
由 3个类构成
![](/icons/9327dou.gif)
第
![](/icons/9327yi.gif)
个是TestThreadPool类
![](/icons/9327dou.gif)
它是
![](/icons/9327yi.gif)
个测试
![](/icons/9327chengxu.gif)
![](/icons/9327dou.gif)
用来模拟客户端
![](/icons/9327de.gif)
请求
![](/icons/9327dou.gif)
当你运行它时
![](/icons/9327dou.gif)
系统首先会显示线程池
![](/icons/9327de.gif)
![](/icons/9327chushi.gif)
化信息
![](/icons/9327dou.gif)
然后提示你从键盘上输入
![](/icons/9327zifu.gif)
串
![](/icons/9327dou.gif)
并按下回车键
![](/icons/9327dou.gif)
这时你会发现屏幕上显示信息
![](/icons/9327dou.gif)
告诉你某个线程正在处理你
![](/icons/9327de.gif)
请求
![](/icons/9327dou.gif)
如果你快速地输入
![](/icons/9327yi.gif)
行行
![](/icons/9327zifu.gif)
串
![](/icons/9327dou.gif)
那么你会发现线程池中不断有线程被唤醒
![](/icons/9327dou.gif)
来处理你
![](/icons/9327de.gif)
请求
![](/icons/9327dou.gif)
在本例中
![](/icons/9327dou.gif)
我创建了
![](/icons/9327yi.gif)
个拥有10个线程
![](/icons/9327de.gif)
线程池
![](/icons/9327dou.gif)
如果线程池中没有可用线程了
![](/icons/9327dou.gif)
系统会提示你相应
![](/icons/9327de.gif)
警告信息
![](/icons/9327dou.gif)
但如果你稍等片刻
![](/icons/9327dou.gif)
那你会发现屏幕上会陆陆续续提示有线程进入了睡眠状态
![](/icons/9327dou.gif)
这时你又可以发送新
![](/icons/9327de.gif)
请求了
![](/icons/9327dou2.gif)
第 2个类是ThreadPoolManager类
![](/icons/9327dou.gif)
顾名思义
![](/icons/9327dou.gif)
它是
![](/icons/9327yi.gif)
个用于管理线程池
![](/icons/9327de.gif)
类
![](/icons/9327dou.gif)
它
![](/icons/9327de.gif)
主要职责是
![](/icons/9327chushi.gif)
化线程池
![](/icons/9327dou.gif)
并为客户端
![](/icons/9327de.gif)
请求分配区别
![](/icons/9327de.gif)
线程来进行处理
![](/icons/9327dou.gif)
如果线程池满了
![](/icons/9327dou.gif)
它会对你发出警告信息
![](/icons/9327dou2.gif)
最后
![](/icons/9327yi.gif)
个类是SimpleThread类
![](/icons/9327dou.gif)
它是Thread类
![](/icons/9327de.gif)
![](/icons/9327yi.gif)
个子类
![](/icons/9327dou.gif)
它才真正对客户端
![](/icons/9327de.gif)
请求进行处理
![](/icons/9327dou.gif)
SimpleThread在举例
![](/icons/9327chengxu.gif)
![](/icons/9327chushi.gif)
化时都处于睡眠状态
![](/icons/9327dou.gif)
但如果它接受到了ThreadPoolManager类发过来
![](/icons/9327de.gif)
调度信息
![](/icons/9327dou.gif)
则会将自己唤醒
![](/icons/9327dou.gif)
并对请求进行处理
首先我们来看
![](/icons/9327yi.gif)
下TestThreadPool类
![](/icons/9327de.gif)
源码:
//TestThreadPool.java
1 import java.io.*;
2
3
4 public
![](/icons/9327class.gif)
TestThreadPool
5 {
6 public
![](/icons/9327static.gif)
void
![](/icons/9327main.gif)
(String
![](/icons/9327zhk2.gif)
args)
7 {
8 try{
9 BufferedReader br =
![](/icons/9327new.gif)
BufferedReader(
![](/icons/9327new.gif)
InputStreamReader(
![](/icons/9327System.gif)
.in));
10 String s;
11 ThreadPoolManager manager =
![](/icons/9327new.gif)
ThreadPoolManager(10);
12 while((s = br.readLine
![](/icons/9327kh.gif)
) != null)
13 {
14 manager.process(s);
15 }
16 }catch(IOException e){}
17 }
18 }
由于此测试
![](/icons/9327chengxu.gif)
用到了输入输入类
![](/icons/9327dou.gif)
因此第1行导入了JAVA
![](/icons/9327de.gif)
基本IO处理包
![](/icons/9327dou.gif)
在第11行中
![](/icons/9327dou.gif)
我们创建了
![](/icons/9327yi.gif)
个名为manager
![](/icons/9327de.gif)
类
![](/icons/9327dou.gif)
它给ThreadPoolManager类
![](/icons/9327de.gif)
构造
![](/icons/9327hanshu.gif)
传递了
![](/icons/9327yi.gif)
个值为10
![](/icons/9327de.gif)
参数
![](/icons/9327dou.gif)
告诉ThreadPoolManager类:我要
![](/icons/9327yi.gif)
个有10个线程
![](/icons/9327de.gif)
池
![](/icons/9327dou.gif)
给我创建
![](/icons/9327yi.gif)
个吧!第12行至15行是
![](/icons/9327yi.gif)
个无限循环
![](/icons/9327dou.gif)
它用来等待用户
![](/icons/9327de.gif)
键入
![](/icons/9327dou.gif)
并将键入
![](/icons/9327de.gif)
![](/icons/9327zifu.gif)
串保存在s变量中
![](/icons/9327dou.gif)
并
![](/icons/9327diaoyong.gif)
ThreadPoolManager类
![](/icons/9327de.gif)
process思路方法来将这个请求进行处理
![](/icons/9327dou2.gif)
下面我们再进
![](/icons/9327yi.gif)
步跟踪到ThreadPoolManager类中去
![](/icons/9327dou.gif)
以下是它
![](/icons/9327de.gif)
源代码:
//ThreadPoolManager.java
1 import java.util.*;
2
3
4
![](/icons/9327class.gif)
ThreadPoolManager
5 {
6
7 private
![](/icons/9327int.gif)
maxThread;
8 public Vector vector;
9 public void
![](/icons/9327set.gif)
MaxThread(
![](/icons/9327int.gif)
threadCount)
10 {
11 maxThread = threadCount;
12 }
13
14 public ThreadPoolManager(
![](/icons/9327int.gif)
threadCount)
15 {
16
![](/icons/9327set.gif)
MaxThread(threadCount);
17
![](/icons/9327System.gif)
.out.pr
![](/icons/9327int.gif)
ln("Starting thread pool...");
18 vector =
![](/icons/9327new.gif)
Vector
![](/icons/9327kh.gif)
;
19 for(
![](/icons/9327int.gif)
i = 1; i <= 10; i
![](/icons/9327jiajia.gif)
)
20 {
21 SimpleThread thread =
![](/icons/9327new.gif)
SimpleThread(i);
22 vector.addElement(thread);
23 thread.start
![](/icons/9327kh.gif)
;
24 }
25 }
26
27 public void process(String argument)
28 {
29
![](/icons/9327int.gif)
i;
30 for(i = 0; i < vector.size
![](/icons/9327kh.gif)
; i
![](/icons/9327jiajia.gif)
)
31 {
32 SimpleThread currentThread = (SimpleThread)vector.elementAt(i);
33
![](/icons/9327if.gif)
(!currentThread.isRunning
![](/icons/9327kh.gif)
)
34 {
35
![](/icons/9327System.gif)
.out.pr
![](/icons/9327int.gif)
ln("Thread "+ (i+1) +" is processing:" +
argument);
36 currentThread.
![](/icons/9327set.gif)
Argument(argument);
37 currentThread.
![](/icons/9327set.gif)
Running(true);
38
![](/icons/9327return.gif)
;
39 }
40 }
41
![](/icons/9327if.gif)
(i
![](/icons/9327dd.gif)
vector.size
![](/icons/9327kh.gif)
)
42 {
43
![](/icons/9327System.gif)
.out.pr
![](/icons/9327int.gif)
ln("pool is full, try in another time.");
44 }
45 }
46 }//end of
![](/icons/9327class.gif)
ThreadPoolManager
我们先关注
![](/icons/9327yi.gif)
下这个类
![](/icons/9327de.gif)
构造
![](/icons/9327hanshu.gif)
![](/icons/9327dou.gif)
然后再看它
![](/icons/9327de.gif)
process
![](/icons/9327kh.gif)
思路方法
![](/icons/9327dou2.gif)
第16-24行是它
![](/icons/9327de.gif)
构造
![](/icons/9327hanshu.gif)
![](/icons/9327dou.gif)
首先它给ThreadPoolManager类
![](/icons/9327de.gif)
成员变量maxThread赋值
![](/icons/9327dou.gif)
maxThread表示用于控制线程池中最大线程
![](/icons/9327de.gif)
数量
![](/icons/9327dou2.gif)
第18行
![](/icons/9327chushi.gif)
化
![](/icons/9327yi.gif)
个
![](/icons/9327shuzu.gif)
vector
![](/icons/9327dou.gif)
它用来存放所有
![](/icons/9327de.gif)
SimpleThread类
![](/icons/9327dou.gif)
这时候就充分体现了JAVA语言
![](/icons/9327de.gif)
优越性和艺术性:如果你用C语言
![](/icons/9327de.gif)
话
![](/icons/9327dou.gif)
至少要写100行以上
![](/icons/9327de.gif)
代码来完成vector
![](/icons/9327de.gif)
功能
![](/icons/9327dou.gif)
而且C语言
![](/icons/9327shuzu.gif)
只能容纳类型统
![](/icons/9327yi.gif)
![](/icons/9327de.gif)
基本数据类型
![](/icons/9327dou.gif)
无法容纳对象
![](/icons/9327dou2.gif)
好了
![](/icons/9327dou.gif)
闲话少说
![](/icons/9327dou.gif)
第19-24行
![](/icons/9327de.gif)
循环完成这样
![](/icons/9327yi.gif)
个功能:先创建
![](/icons/9327yi.gif)
个新
![](/icons/9327de.gif)
SimpleThread类
![](/icons/9327dou.gif)
然后将它放入vector中去
![](/icons/9327dou.gif)
最后用thread.start
![](/icons/9327kh.gif)
来启动这个线程
![](/icons/9327dou.gif)
为什么要用start
![](/icons/9327kh.gif)
思路方法来启动线程呢?
![](/icons/9327yinwei.gif)
这是JAVA语言中所规定
![](/icons/9327de.gif)
![](/icons/9327dou.gif)
如果你不用
![](/icons/9327de.gif)
话
![](/icons/9327dou.gif)
那这些线程将永远得不到激活
![](/icons/9327dou.gif)
从而导致本举例
![](/icons/9327chengxu.gif)
根本无法运行
![](/icons/9327dou2.gif)
下面我们再来看
![](/icons/9327yi.gif)
下process
![](/icons/9327kh.gif)
思路方法
![](/icons/9327dou.gif)
第30-40行
![](/icons/9327de.gif)
循环依次从vector
![](/icons/9327shuzu.gif)
中选取SimpleThread线程
![](/icons/9327dou.gif)
并检查它是否处于激活状态(所谓激活状态是指此线程是否正在处理客户端
![](/icons/9327de.gif)
请求)
![](/icons/9327dou.gif)
如果处于激活状态
![](/icons/9327de.gif)
话
![](/icons/9327dou.gif)
那继续查找vector
![](/icons/9327shuzu.gif)
![](/icons/9327de.gif)
下
![](/icons/9327yi.gif)
项
![](/icons/9327dou.gif)
如果vector
![](/icons/9327shuzu.gif)
中所有
![](/icons/9327de.gif)
线程都处于激活状态
![](/icons/9327de.gif)
话
![](/icons/9327dou.gif)
那它会打印出
![](/icons/9327yi.gif)
条信息
![](/icons/9327dou.gif)
提示用户稍候再试
![](/icons/9327dou2.gif)
相反如果找到了
![](/icons/9327yi.gif)
个睡眠线程
![](/icons/9327de.gif)
话
![](/icons/9327dou.gif)
那第35-38行会对此进行处理
![](/icons/9327dou.gif)
它先告诉客户端是哪
![](/icons/9327yi.gif)
个线程来处理这个请求
![](/icons/9327dou.gif)
然后将客户端
![](/icons/9327de.gif)
请求
![](/icons/9327dou.gif)
即
![](/icons/9327zifu.gif)
串argument转发给SimpleThread类
![](/icons/9327de.gif)
![](/icons/9327set.gif)
Argument
![](/icons/9327kh.gif)
思路方法进行处理
![](/icons/9327dou.gif)
并
![](/icons/9327diaoyong.gif)
SimpleThread类
![](/icons/9327de.gif)
![](/icons/9327set.gif)
Running
![](/icons/9327kh.gif)
思路方法来唤醒当前线程
![](/icons/9327dou.gif)
来对客户端请求进行处理
![](/icons/9327dou2.gif)
可能你还对
![](/icons/9327set.gif)
Running
![](/icons/9327kh.gif)
思路方法是怎样唤醒线程
![](/icons/9327de.gif)
有些不明白
![](/icons/9327dou.gif)
那我们现在就进入最后
![](/icons/9327yi.gif)
个类:SimpleThread类
![](/icons/9327dou.gif)
它
![](/icons/9327de.gif)
源代码如下:
//SimpleThread.java
1
![](/icons/9327class.gif)
SimpleThread extends Thread
2 {
3 private boolean runningFlag;
4 private String argument;
5 public boolean isRunning
![](/icons/9327kh.gif)
6 {
7
![](/icons/9327return.gif)
runningFlag;
8 }
9 public synchronized void
![](/icons/9327set.gif)
Running(boolean flag)
10 {
11 runningFlag = flag;
12
![](/icons/9327if.gif)
(flag)
13 this.not
![](/icons/9327if.gif)
y
![](/icons/9327kh.gif)
;
14 }
15
16 public String getArgument
![](/icons/9327kh.gif)
17 {
18
![](/icons/9327return.gif)
this.argument;
19 }
20 public void
![](/icons/9327set.gif)
Argument(String
![](/icons/9327string.gif)
)
21 {
22 argument =
![](/icons/9327string.gif)
;
23 }
24
25 public SimpleThread(
![](/icons/9327int.gif)
threadNumber)
26 {
27 runningFlag = false;
28
![](/icons/9327System.gif)
.out.pr
![](/icons/9327int.gif)
ln("thread " + threadNumber + "started.");
29 }
30
31 public synchronized void run
![](/icons/9327kh.gif)
32 {
33 try{
34 while(true)
35 {
36
![](/icons/9327if.gif)
(!runningFlag)
37 {
38 this.wait
![](/icons/9327kh.gif)
;
39 }
40
![](/icons/9327else.gif)
41 {
42
![](/icons/9327System.gif)
.out.pr
![](/icons/9327int.gif)
ln("processing " + getArgument
![](/icons/9327kh.gif)
+ "... done.");
43 sleep(5000);
44
![](/icons/9327System.gif)
.out.pr
![](/icons/9327int.gif)
ln("Thread is sleeping...");
45
![](/icons/9327set.gif)
Running(false);
46 }
47 }
48 } catch(InterruptedException e){
49
![](/icons/9327System.gif)
.out.pr
![](/icons/9327int.gif)
ln("Interrupt");
50 }
51 }//end of run
![](/icons/9327kh.gif)
52 }//end of
![](/icons/9327class.gif)
SimpleThread
如果你对JAVA
![](/icons/9327de.gif)
线程编程有些不太明白
![](/icons/9327de.gif)
话
![](/icons/9327dou.gif)
那我先在这里简单地讲解
![](/icons/9327yi.gif)
下
![](/icons/9327dou.gif)
JAVA有
![](/icons/9327yi.gif)
个名为Thread
![](/icons/9327de.gif)
类
![](/icons/9327dou.gif)
如果你要创建
![](/icons/9327yi.gif)
个线程
![](/icons/9327dou.gif)
则必须要从Thread类中继承
![](/icons/9327dou.gif)
并且还要实现Thread类
![](/icons/9327de.gif)
run
![](/icons/9327kh.gif)
接口
![](/icons/9327dou.gif)
要激活
![](/icons/9327yi.gif)
个线程
![](/icons/9327dou.gif)
必须
![](/icons/9327diaoyong.gif)
它
![](/icons/9327de.gif)
start
![](/icons/9327kh.gif)
思路方法
![](/icons/9327dou.gif)
start
![](/icons/9327kh.gif)
思路方法会自动
![](/icons/9327diaoyong.gif)
run
![](/icons/9327kh.gif)
接口
![](/icons/9327dou.gif)
因此用户必须在run
![](/icons/9327kh.gif)
接口中写入自己
![](/icons/9327de.gif)
应用处理逻辑
![](/icons/9327dou2.gif)
那么我们如何来控制线程
![](/icons/9327de.gif)
睡眠和唤醒呢?其实很简单
![](/icons/9327dou.gif)
JAVA语言为所有
![](/icons/9327de.gif)
对象都内置了wait
![](/icons/9327kh.gif)
和not
![](/icons/9327if.gif)
y
![](/icons/9327kh.gif)
思路方法
![](/icons/9327dou.gif)
当
![](/icons/9327yi.gif)
个线程
![](/icons/9327diaoyong.gif)
wait
![](/icons/9327kh.gif)
思路方法时
![](/icons/9327dou.gif)
则线程进入睡眠状态
![](/icons/9327dou.gif)
就像停在了当前代码上了
![](/icons/9327dou.gif)
也不会继续执行它以下
![](/icons/9327de.gif)
代码了
![](/icons/9327dou.gif)
当
![](/icons/9327diaoyong.gif)
not
![](/icons/9327if.gif)
y
![](/icons/9327kh.gif)
思路方法时
![](/icons/9327dou.gif)
则会从
![](/icons/9327diaoyong.gif)
wait
![](/icons/9327kh.gif)
思路方法
![](/icons/9327de.gif)
那行代码继续执行以下
![](/icons/9327de.gif)
代码
![](/icons/9327dou.gif)
这个过程有点像编译器中
![](/icons/9327de.gif)
断点调试
![](/icons/9327de.gif)
概念
![](/icons/9327dou2.gif)
以本
![](/icons/9327chengxu.gif)
为例
![](/icons/9327dou.gif)
第38行
![](/icons/9327diaoyong.gif)
了wait
![](/icons/9327kh.gif)
思路方法
![](/icons/9327dou.gif)
则这个线程就像凝固了
![](/icons/9327yi.gif)
样停在了38行上了
![](/icons/9327dou.gif)
如果我们在第13行进行
![](/icons/9327yi.gif)
个not
![](/icons/9327if.gif)
y
![](/icons/9327kh.gif)
![](/icons/9327diaoyong.gif)
![](/icons/9327de.gif)
话
![](/icons/9327dou.gif)
那线程会从第38行上唤醒
![](/icons/9327dou.gif)
继续从第39行开始执行以下
![](/icons/9327de.gif)
代码了
![](/icons/9327dou2.gif)
通过以上
![](/icons/9327de.gif)
讲述
![](/icons/9327dou.gif)
我们现在就不难理解SimpleThread类了
![](/icons/9327dou.gif)
第9-14行通过设置
![](/icons/9327yi.gif)
个标志runningFlag激活当前线程
![](/icons/9327dou.gif)
第25-29行是SimpleThread类
![](/icons/9327de.gif)
构造
![](/icons/9327hanshu.gif)
![](/icons/9327dou.gif)
它用来告诉客户端启动
![](/icons/9327de.gif)
是第几号进程
![](/icons/9327dou2.gif)
第31-50行则是我实现
![](/icons/9327de.gif)
run
![](/icons/9327kh.gif)
接口
![](/icons/9327dou.gif)
它实际上是
![](/icons/9327yi.gif)
个无限循环
![](/icons/9327dou.gif)
在循环中首先判断
![](/icons/9327yi.gif)
下标志runningFlag
![](/icons/9327dou.gif)
如果没有runningFlag为false
![](/icons/9327de.gif)
话
![](/icons/9327dou.gif)
那线程处理睡眠状态
![](/icons/9327dou.gif)
否则第42-45行会进行真正
![](/icons/9327de.gif)
处理:先打印用户键入
![](/icons/9327de.gif)
![](/icons/9327zifu.gif)
串
![](/icons/9327dou.gif)
然后睡眠5秒钟
![](/icons/9327dou.gif)
为什么要睡眠5秒钟呢?如果你不加上这句代码
![](/icons/9327de.gif)
话
![](/icons/9327dou.gif)
由于计算机处理速度远远超过你
![](/icons/9327de.gif)
键盘输入速度
![](/icons/9327dou.gif)
因此你看到
![](/icons/9327de.gif)
总是第1号线程来处理你
![](/icons/9327de.gif)
请求
![](/icons/9327dou.gif)
从而达不到演示效果
![](/icons/9327dou2.gif)
最后第45行
![](/icons/9327diaoyong.gif)
![](/icons/9327set.gif)
Running
![](/icons/9327kh.gif)
思路方法又将线程置于睡眠状态
![](/icons/9327dou.gif)
等待新请求
![](/icons/9327de.gif)
到来
![](/icons/9327dou2.gif)
最后还有
![](/icons/9327yi.gif)
点要注意
![](/icons/9327de.gif)
是
![](/icons/9327dou.gif)
如果你在
![](/icons/9327yi.gif)
个思路方法中
![](/icons/9327diaoyong.gif)
了wait
![](/icons/9327kh.gif)
和not
![](/icons/9327if.gif)
y
![](/icons/9327kh.gif)
![](/icons/9327hanshu.gif)
![](/icons/9327dou.gif)
那你
![](/icons/9327yi.gif)
定要将此思路方法置为同步
![](/icons/9327de.gif)
![](/icons/9327dou.gif)
即synchronized
![](/icons/9327dou.gif)
否则在编译时会报错
![](/icons/9327dou.gif)
并得到
![](/icons/9327yi.gif)
个莫名其妙
![](/icons/9327de.gif)
消息:“current thread not owner”(当前线程不是拥有者)
![](/icons/9327dou2.gif)
至此为止
![](/icons/9327dou.gif)
我们完整地实现了
![](/icons/9327yi.gif)
个线程池
![](/icons/9327dou.gif)
当然
![](/icons/9327dou.gif)
这个线程池只是简单地将客户端输入
![](/icons/9327de.gif)
![](/icons/9327zifu.gif)
串打印到了屏幕上
![](/icons/9327dou.gif)
而没有做任何处理
![](/icons/9327dou.gif)
对于
![](/icons/9327yi.gif)
个真正
![](/icons/9327de.gif)
企业级运用
![](/icons/9327dou.gif)
本例还是远远不够
![](/icons/9327de.gif)
![](/icons/9327dou.gif)
例如
![](/icons/9327cuowu.gif)
处理、线程
![](/icons/9327de.gif)
动态调整、性能优化、临界区
![](/icons/9327de.gif)
处理、客户端报文
![](/icons/9327de.gif)
定义等等都是值得考虑
![](/icons/9327de.gif)
问题
![](/icons/9327dou.gif)
但本文
![](/icons/9327de.gif)
目
![](/icons/9327de.gif)
仅仅只是让你了解线程池
![](/icons/9327de.gif)
概念以及它
![](/icons/9327de.gif)
简单实现
![](/icons/9327dou.gif)
如果你想成为这方面
![](/icons/9327de.gif)
高手
![](/icons/9327dou.gif)
本文是远远不够
![](/icons/9327de.gif)
![](/icons/9327dou.gif)
你应该参考
![](/icons/9327yi.gif)
些更多
![](/icons/9327de.gif)
资料来深入地了解它