java自己实现线程池,java中线程池的创建与使用

  java自己实现线程池,java中线程池的创建与使用

  Java代码构建线程池-鱼河专栏-博客频道-CSDN。网

  Java代码构建了一个线程池。

  2005-10-26 16:42

  62人阅读

  评论(0)

  收集

  这个示例报告程序包含三个类。第一个是TestThreadPool类,这是一个用于模拟客户端请求的测试程序。当您运行它时,系统将首先显示线程池的初始化信息,然后提示您从键盘输入一个字符串并按回车键。这时,你会发现屏幕上显示的信息告诉你某个线程正在处理你的请求。如果您快速地逐行输入一个字符串,那么您会发现线程池中的线程会不断地被唤醒来处理您的请求。在这个例子中,我创建了一个有10个线程的线程池。如果线程池中没有可用的线程,系统会用相应的警告信息提示您。但是如果你等一会儿,然后你会发现屏幕会提示一个又一个线程进入睡眠状态。此时,您可以再次发送新的请求。

  第二个类是ThreadPoolManager类。顾名思义,它是一个用于管理线程池的类。它的主要职责是初始化线程池,并将不同的线程分配给客户端的请求进行处理。如果线程池已满,它会给你一个警告消息。

  最后一个类是SimpleThread类,它是Thread类的子类。它真正处理客户的请求。当示例程序初始化时,SimpleThread处于睡眠状态,但如果它接收到ThreadPoolManager类发送的调度信息,它将唤醒自己并处理请求。

  让我们先来看看TestThreadPool类的源代码:

  //TestThreadPool.java

  1导入Java . io . *;

  2

  三

  4公共类TestThreadPool

  5 {

  6公共静态void main(String[] args)

  7 {

  8尝试{

  9 buffered reader br=new buffered reader(new InputStreamReader(system . in));

  10串s;

  11 ThreadPoolManager manager=new ThreadPoolManager(10);

  12 while((s=br.readLine())!=空)

  13 {

  14个经理流程;

  15 }

  16 }catch(IOException e){}

  17 }

  18 }

  因为这个测试程序使用了input-input类,所以JAVA的基本IO处理包是在第1行导入的。在第11行,我们创建了一个名为manager的类,它将一个值为10的参数传递给ThreadPoolManager类的构造函数,并告诉ThreadPoolManager类:我想要一个有10个线程的池,给我创建一个吧!第12行到第15行是一个无限循环,用来等待用户的键入,将键入的字符串保存在S变量中,调用ThreadPoolManager类的process方法来处理这个请求。

  让我们进一步追溯到ThreadPoolManager类。下面是它的源代码:

  //ThreadPoolManager.java

  1导入Java . util . *;

  2

  三

  4类ThreadPoolManager

  5 {

  六

  7 private int maxThread

  8公共向量向量;

  9 public void setMaxThread(int thread count)

  10 {

  11 maxThread=threadCount

  12 }

  13

  14公共线程池管理器(int threadCount)

  15 {

  16 setMaxThread(thread count);

  17 System.out.println(启动线程池.);

  18向量=新向量();

  19 for(int I=1;i=10我)

  20 {

  21 simple thread thread=new simple thread(I);

  22 vector.addElement(线程);

  23 thread.start()。

  24 }

  25 }

  26

  27公共void进程(字符串参数)

  28 {

  29 int I;

  30 for(I=0;I vector . size();我)

  31 {

  32 simple thread current thread=(simple thread)vector . element at(I);

  33如果(!currentThread.isRunning())

  34 {

  35 system . out . println( Thread (I 1)正在处理:

  论据);

  36 currentThread.setArgument(参数);

  37 currentThread.setRunning(真);

  38返回;

  39 }

  40 }

  41 if(i==vector.size())

  42 {

  43 System.out.println(池已满,下次再试。);

  44 }

  45 }

  46 }//ThreadPoolManager类的结尾

  我们先来关注一下这个类的构造函数,然后再来看它的process()方法。第16-24行是它的构造函数。首先,它为ThreadPoolManager类的成员变量maxThread赋值。maxThread表示它用于控制线程池中线程的最大数量。第18行初始化一个数组向量,用于存储所有SimpleThread类。这时候就充分体现了JAVA语言的优越性和艺术性:如果用C语言,至少要写100行代码才能完成vector的功能。而且C语言数组只能容纳统一类型的基本数据类型,不能容纳对象。好吧,我们长话短说。第19-24行的循环完成了这样一个功能:首先创建一个新的SimpleThread类,然后放入vector,最后用thread.start()启动线程。为什么要用start()方法启动线程?因为这是JAVA语言规定的,如果不使用,那么这些线程永远不会被激活,导致这个示例程序根本无法运行。

  我们再来看看process()方法。第30-40行的循环依次从vector数组中选择SimpleThread线程,检查它是否处于活动状态(所谓活动状态是指这个线程是否在处理客户端的请求)。如果它是活动的,继续寻找向量数组中的下一项。如果vector数组中的所有线程都是活动的,它将打印出一条消息,提示用户稍后再试。相反,如果发现一个休眠线程,第35-38行将会处理它。它首先告诉客户端哪个线程将处理请求,然后将客户端的请求,即字符串参数,转发给SimpleThread类的setArgument()方法进行处理,并调用SimpleThread类的setRunning()方法唤醒当前线程处理客户端的请求。

  也许你还不明白setRunning()方法是如何唤醒线程的,那么我们现在来看最后一个类:SimpleThread类,它的源代码如下:

  //SimpleThread.java

  1类SimpleThread扩展线程

  2 {

  3私有布尔runningFlag

  4私有字符串参数;

  5 public boolean isRunning()

  6 {

  7返回runningFlag

  8 }

  9公共同步void setRunning(布尔标志)

  10 {

  11 runningFlag=flag

  12如果(标志)

  13 this . notify();

  14 }

  15

  16公共字符串getArgument()

  17 {

  返回this.argument

  19 }

  20 public void setArgument(String字符串)

  21 {

  22自变量=字符串;

  23 }

  24

  25公共简单线程(int threadNumber)

  26 {

  27 runningFlag=false

  28 system . out . println( thread thread number 已启动。);

  29 }

  30

  31公共同步无效运行()

  32 {

  33尝试{

  34 while(真)

  35 {

  36如果(!运行标志)

  37 {

  38 this . wait();

  39 }

  其他40个

  41 {

  42 system . out . println( processing get argument().“成交。”);

  43睡眠(5000);

  44 System.out.println(线程正在休眠.);

  45 setRunning(假);

  46 }

  47 }

  48 } catch(中断异常e){

  49 System.out.println(中断);

  50 }

  51 }//运行结束()

  52 }//类SimpleThread的结尾

  如果你不懂JAVA的线程编程,我在这里简单解释一下。JAVA有一个名为Thread的类。如果要创建线程,必须从Thread类继承,还必须实现Thread类的run()接口。要激活一个线程,必须调用它的start()方法,这个方法会自动调用run()接口,所以用户必须在so我们如何控制线程的睡眠和唤醒中调用start()接口?其实很简单。JAVA语言为所有对象内置了wait()和notify()方法。当一个线程调用wait()方法时,线程进入睡眠状态,就像它在当前代码处停止一样,它不会继续执行它下面的代码。当调用notify()方法时,下面的代码将从调用wait()方法的那一行继续执行,这有点像在编译器中。以这个节目为例。当在第38行调用wait()方法时,线程在第38行停止,就像被冻结了一样。如果我们在第13行调用notify(),线程将从第38行唤醒,并继续执行第39行的代码。

  通过以上,我们现在就不难理解SimpleThread类了。第9-14行通过设置一个标志runningFlag来激活当前线程,第25-29行是SimpleThread类的构造函数,用来告诉客户端启动哪个进程。第31-50行是我实现的run()接口。它实际上是一个无限循环。在循环中,首先判断flag runningFlag。如果no runningFlag为false,那么线程将处理睡眠状态,否则第42-45行将进行真正的处理:首先打印用户键入的字符串,然后睡眠5秒钟。为什么要睡5秒?如果不加这段代码,因为电脑的处理速度远远快于你键盘的输入速度,你看到的永远是1号线程处理你的请求,所以演示效果达不到。最后一行45调用setRunning()方法让线程休眠并等待新的请求。

  最后需要注意的是,如果在一个方法中调用wait()和notify()函数,必须将这个方法设置为synchronized,也就是synchronized,否则编译时会报错,得到一个莫名其妙的消息:“当前线程不是所有者”(当前线程不是所有者)。分享到:上一篇:简单线程缓冲池的实现

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: