专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Java教程 » java线程池:100行Java代码构建一个线程池 »正文

java线程池:100行Java代码构建一个线程池

来源: 发布时间:星期三, 2008年12月17日 浏览:61次 评论:0
    本举例由 3个类构成个是TestThreadPool类它是个测试用来模拟客户端请求当你运行它时系统首先会显示线程池化信息然后提示你从键盘上输入并按下回车键这时你会发现屏幕上显示信息告诉你某个线程正在处理你请求如果你快速地输入行行那么你会发现线程池中不断有线程被唤醒来处理你请求在本例中我创建了个拥有10个线程线程池如果线程池中没有可用线程了系统会提示你相应警告信息但如果你稍等片刻那你会发现屏幕上会陆陆续续提示有线程进入了睡眠状态这时你又可以发送新请求了

  第 2个类是ThreadPoolManager类顾名思义它是个用于管理线程池主要职责是化线程池并为客户端请求分配区别线程来进行处理如果线程池满了它会对你发出警告信息

  最后个类是SimpleThread类它是Thread类个子类它才真正对客户端请求进行处理SimpleThread在举例化时都处于睡眠状态但如果它接受到了ThreadPoolManager类发过来调度信息则会将自己唤醒并对请求进行处理

首先我们来看下TestThreadPool类源码:

 //TestThreadPool.java
1 import java.io.*;
2
3
4 public TestThreadPool
5 {
6 public void (String args)
7 {
8 try{
9 BufferedReader br = BufferedReader( InputStreamReader(.in));
10 String s;
11 ThreadPoolManager manager = ThreadPoolManager(10);
12 while((s = br.readLine) != null)
13 {
14 manager.process(s);
15 }
16 }catch(IOException e){}
17 }
18 } 

 由于此测试用到了输入输入类因此第1行导入了JAVA基本IO处理包在第11行中我们创建了个名为manager它给ThreadPoolManager类构造传递了个值为10参数告诉ThreadPoolManager类:我要个有10个线程给我创建个吧!第12行至15行是个无限循环它用来等待用户键入并将键入串保存在s变量中ThreadPoolManager类process思路方法来将这个请求进行处理

下面我们再进步跟踪到ThreadPoolManager类中去以下是它源代码:

 //ThreadPoolManager.java
1 import java.util.*;
2
3
4 ThreadPoolManager
5 {
6
7 private maxThread;
8 public Vector vector;
9 public void MaxThread( threadCount)
10 {
11 maxThread = threadCount;
12 }
13
14 public ThreadPoolManager( threadCount)
15 {
16 MaxThread(threadCount);
17 .out.prln("Starting thread pool...");
18 vector = Vector;
19 for( i = 1; i <= 10; i)
20 {
21 SimpleThread thread = SimpleThread(i);
22 vector.addElement(thread);
23 thread.start;
24 }
25 }
26
27 public void process(String argument)
28 {
29 i;
30 for(i = 0; i < vector.size; i)
31 {
32 SimpleThread currentThread = (SimpleThread)vector.elementAt(i);
33 (!currentThread.isRunning)
34 {
35 .out.prln("Thread "+ (i+1) +" is processing:" +
argument);
36 currentThread.Argument(argument);
37 currentThread.Running(true);
38 ;
39 }
40 }
41 (i vector.size)
42 {
43 .out.prln("pool is full, try in another time.");
44 }
45 }
46 }//end of ThreadPoolManager 

我们先关注下这个类构造然后再看它process思路方法第16-24行是它构造首先它给ThreadPoolManager类成员变量maxThread赋值maxThread表示用于控制线程池中最大线程数量第18行vector它用来存放所有SimpleThread类这时候就充分体现了JAVA语言优越性和艺术性:如果你用C语言至少要写100行以上代码来完成vector功能而且C语言只能容纳类型统基本数据类型无法容纳对象好了闲话少说第19-24行循环完成这样个功能:先创建个新SimpleThread类然后将它放入vector中去最后用thread.start来启动这个线程为什么要用start思路方法来启动线程呢?这是JAVA语言中所规定如果你不用那这些线程将永远得不到激活从而导致本举例根本无法运行

  下面我们再来看下process思路方法第30-40行循环依次从vector中选取SimpleThread线程并检查它是否处于激活状态(所谓激活状态是指此线程是否正在处理客户端请求)如果处于激活状态那继续查找vector如果vector中所有线程都处于激活状态那它会打印出条信息提示用户稍候再试相反如果找到了个睡眠线程那第35-38行会对此进行处理它先告诉客户端是哪个线程来处理这个请求然后将客户端请求串argument转发给SimpleThread类Argument思路方法进行处理SimpleThread类Running思路方法来唤醒当前线程来对客户端请求进行处理

可能你还对Running思路方法是怎样唤醒线程有些不明白那我们现在就进入最后个类:SimpleThread类源代码如下:

 //SimpleThread.java
1 SimpleThread extends Thread
2 {
3 private boolean runningFlag;
4 private String argument;
5 public boolean isRunning
6 {
7 runningFlag;
8 }
9 public synchronized void Running(boolean flag)
10 {
11 runningFlag = flag;
12 (flag)
13 this.noty;
14 }
15
16 public String getArgument
17 {
18 this.argument;
19 }
20 public void Argument(String )
21 {
22 argument = ;
23 }
24
25 public SimpleThread( threadNumber)
26 {
27 runningFlag = false;
28 .out.prln("thread " + threadNumber + "started.");
29 }
30
31 public synchronized void run
32 {
33 try{
34 while(true)
35 {
36 (!runningFlag)
37 {
38 this.wait;
39 }
40
41 {
42 .out.prln("processing " + getArgument + "... done.");
43 sleep(5000);
44 .out.prln("Thread is sleeping...");
45 Running(false);
46 }
47 }
48 } catch(InterruptedException e){
49 .out.prln("Interrupt");
50 }
51 }//end of run
52 }//end of SimpleThread 

如果你对JAVA线程编程有些不太明白那我先在这里简单地讲解JAVA有个名为Thread如果你要创建个线程则必须要从Thread类中继承并且还要实现Thread类run接口要激活个线程必须start思路方法start思路方法会自动run接口因此用户必须在run接口中写入自己应用处理逻辑那么我们如何来控制线程睡眠和唤醒呢?其实很简单JAVA语言为所有对象都内置了wait和noty思路方法个线程wait思路方法时则线程进入睡眠状态就像停在了当前代码上了也不会继续执行它以下代码了noty思路方法时则会从wait思路方法那行代码继续执行以下代码这个过程有点像编译器中断点调试概念以本为例第38行了wait思路方法则这个线程就像凝固了样停在了38行上了如果我们在第13行进行个noty那线程会从第38行上唤醒继续从第39行开始执行以下代码了

  通过以上讲述我们现在就不难理解SimpleThread类了第9-14行通过设置个标志runningFlag激活当前线程第25-29行是SimpleThread类构造它用来告诉客户端启动是第几号进程第31-50行则是我实现run接口它实际上是个无限循环在循环中首先判断下标志runningFlag如果没有runningFlag为false那线程处理睡眠状态否则第42-45行会进行真正处理:先打印用户键入然后睡眠5秒钟为什么要睡眠5秒钟呢?如果你不加上这句代码由于计算机处理速度远远超过你键盘输入速度因此你看到总是第1号线程来处理你请求从而达不到演示效果最后第45行Running思路方法又将线程置于睡眠状态等待新请求到来

  最后还有点要注意如果你在个思路方法中了wait和noty那你定要将此思路方法置为同步即synchronized否则在编译时会报错并得到个莫名其妙消息:“current thread not owner”(当前线程不是拥有者)

  至此为止我们完整地实现了个线程池当然这个线程池只是简单地将客户端输入串打印到了屏幕上而没有做任何处理对于个真正企业级运用本例还是远远不够例如处理、线程动态调整、性能优化、临界区处理、客户端报文定义等等都是值得考虑问题但本文仅仅只是让你了解线程池概念以及它简单实现如果你想成为这方面高手本文是远远不够你应该参考些更多资料来深入地了解它


0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: