1、注意:将在Worker线程内部等待任务池非空的方式称为正向等待。将在Channel线程提供Worker线程来判断任务池非空的方式称为反向等待。线程池实例1:利用同步方法来实现,使用数组来作为任务池的存放数据结构。在Channel有缓存请求方法和处理请求方法,利用生成者与消费者模式来处理存储请求,利用反向等待来判断任务池的非空状态。Channel参与者:12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455packagewhut.threadpool
2、;/用到了生产者与消费者模式/生成线程池,接受客户端线程的请求,找到一个工作线程分配该客户端请求publicclassChannel privatestaticfinalintMAX_REQUEST =100;/ 并发数目,就是同时可以接受多少个客户端请求/利用数组来存放请求,每次从数组末尾添加请求,从开头移除请求来处理Request requestQueue;/ 存储接受客户线程的数目tail;/下一次存放Request的位置head;/下一次获取Request的位置count;/ 当前request数量WorkerThread threadPool;/ 存储线程池中的工作线程/ 运用数组来
3、存储Channel(intthreads this.requestQueue =newRequestMAX_REQUEST;this.head =0;this.count =threadPool =WorkerThreadthreads;/ 启动工作线程for(inti = i = requestQueue.lengthtrywait(;catch(InterruptedException e requestQueuetail = request;tail = (tail +1 % requestQueue.length;count+;notifyAll(;/ 处理客户端请求线程Request
4、 takeRequest( (count =Request request = requestQueuehead;head = (head +count-;returnrequest;客户端请求线程:importjava.util.Random;/向Channel发送Request请求的ClientThreadextendsThreadChannel channel;Random random=newRandom(;ClientThread(String name,Channel channelsuper(name;this.channel=channel;run(tryfor(inti=0;
5、true;i+Request request=newRequest(getName(,i;channel.putRequest(request;Thread.sleep(random.nextInt(1000;catch(InterruptedException e工作线程:/具体工作线程WorkerThreadWorkerThread(String name,Channel channelwhile(trueRequest request=channel.takeRequest(;request.execute(;线程池实例2:利用同步块来处理,利用Vector来存储客户端请求。在Chann
6、el有缓存请求方法和处理请求方法,利用生成者与消费者模式来处理存储请求,利用正向等待来判断任务池的非空状态。这种实例,可以借鉴到网络ServerSocket处理用户请求的模式中,有很好的扩展性与实用性。利用Vector来存储,依旧是每次集合的最后一个位置添加请求,从开始位置移除请求来处理。whut.threadpool2;java.util.Vector;/* 这个主要的作用如下* 0,缓冲客户请求线程(利用生产者与消费者模式* 1,存储客户端请求的线程* 2,初始化启动一定数量的线程* 3,主动来唤醒处于任务池中wait set的一些线程来执行任务*/THREAD_COUNT=4;main(
7、String args /定义两个集合,一个是存放客户端请求的,利用Vector,/一个是存储线程的,就是线程池中的线程数目/Vector是线程安全的,它实现了Collection和List/Vector 类可以实现可增长的对象数组。与数组一样,/它包含可以使用整数索引进行访问的组件。但Vector 的大小可以根据需要增大或缩小,/以适应创建 Vector 后进行添加或移除项的操作。/Collection中主要包括了list相关的集合以及set相关的集合,Queue相关的集合/注意:Map不是Collection的子类,都是java.util.*下的同级包Vector pool=newVect
8、or(;/工作线程,初始分配一定限额的数目WorkerThread workers=newWorkerThreadTHREAD_COUNT;/初始化启动工作线程iworkers.length;workersi=newWorkerThread(pool;workersi.start(;/接受新的任务,并且将其存储在Vector中Object task=newObject(;/模拟的任务实体类/此处省略具体工作/在网络编程中,这里就是利用ServerSocket来利用ServerSocket.accept接受一个Socket从而唤醒线程/当有具体的请求达到synchronized(poolpool
9、.add(pool.size(, task;pool.notifyAll(;/通知所有在pool wait set中等待的线程,唤醒一个线程进行处理/注意上面这步骤添加任务池请求,以及通知线程,都可以放在工作线程内部实现/只需要定义该方法为static,在方法体用同步块,且共享的线程池也是static即可/下面这步,可以有可以没有根据实际情况/取消等待的线程workersi.interrupt(; 工作线程:java.util.List;Thread List pool;/任务请求池fileCompressed=0;/所有实例共享的WorkerThread(List poolthis.pool
10、=pool;/利用静态synchronized来作为整个synchronized类方法,仅能同时一个操作该类的这个方法incrementFilesCompressed(fileCompressed+;/保证无限循环等待中/共享互斥来访问pool变量/利用多线程设计模式中的/Guarded Suspension Pattern,警戒条件为pool不为空,否则无限的等待中while(pool.isEmpty(pool.wait(;/进入pool的wait set中等待着,释放了pool的锁/当线程被唤醒,需要重新获取pool的锁,/再次继续执行synchronized代码块中其余的工作/当不为空的时候,继续再判断是否为空,如果不为空,则跳出循环/必须先从任务池中移除一个任务来执行,统一用从末尾添加,从开始处移除pool.remove(0;/获取任务池中的任务,并且要进行转换/下面是线程所要处理的具体工作