浏览 8810 次
锁定老帖子 主题:线程池的实现
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-07-23
一个线程池由线程池管理器 工作线程 任务队列和任务接口组成 一 线程池管理器---ThreadPoolMananger 主要负责启动 停止工作线程 public class ThreadPoolManager { private static int DEFAULT_POOL_SIZE = 4; private List<WorkThread> threadPool; private Queue<Task> taskQueue; private int poolSize; public ThreadPoolManager(){ this(DEFAULT_POOL_SIZE); } public ThreadPoolManager(int poolSize){ if(poolSize <= 0){ this.poolSize = DEFAULT_POOL_SIZE; }else{ this.poolSize = poolSize; } threadPool = new ArrayList<WorkThread>(this.poolSize); taskQueue = new ConcurrentLinkedQueue<Task>(); startup(); } /** * 启动线程池 开始处理任务 */ private void startup(){ System.out.println("启动工作线程。。。"); synchronized(taskQueue){ for(int i = 0; i < DEFAULT_POOL_SIZE; i++){ WorkThread workThread = new WorkThread(taskQueue); threadPool.add( workThread ); workThread.start(); } } } /** * 停止工作线程。工作线程不一定立即停止,只有在线程处于运行状态时会立即停止 */ public void shutdown(){ System.out.println("停止工作线程."); synchronized(taskQueue){ for(int i = 0; i < DEFAULT_POOL_SIZE; i++){ threadPool.get(i).shutdown(); } } } /** * 添加消息到队尾, */ public void addTask(Task task){ synchronized(taskQueue){ taskQueue.add(task); taskQueue.notifyAll(); } } } 二 工作线程---WorkerThread 顾名思义 它本身就是一个线程,而且是专门用来工作的,工作线程的主要任务是从任务队列中取出任务 然后执行任务 /** * 工作线程 * @author XuLiangYong * Jul 20, 2007 3:47:52 PM */ public class WorkThread extends Thread{ private boolean shutdown = false; private Queue<Task> queue; public WorkThread(Queue<Task> queue){ this.queue = queue; } public void run(){ while(!shutdown){ synchronized(queue){ //获得对象锁 禁止其他线程访问 if(!queue.isEmpty()){ //处理任务 Task task = queue.poll(); task.execute(); }else{ try { queue.wait(); //释放锁 线程处于阻赛状态 等待notify唤醒 } catch (InterruptedException e) { } } } }//end while } /** * 调用该方法后不一定会立即结束线程, 只有在线程处于运行状态且处理完当前任务后才结束 */ public void shutdown(){ shutdown = true; } } 三 任务队列---TaskQueue FIFO数据结构 在出对入队的时候要锁定对象避免两个线程重复处理某任务 在这里我采用的是java提供的ConcurrentLinkedQueue队列,这是一个用链表实现的队 可无限的扩大,具体用法请看doc 用到队列的地方主要有两个 addTask(Task task) 和 Task task = queue.poll(); 四 任务接口---Task 任务接口只有一个方法 execute(),使用者只需实现这个接口就可以了 public interface Task { void execute(); } 用法: public class TestThreadPoolManager extends TestCase { public void test(){ ThreadPoolManager pool = new ThreadPoolManager(); for(int i = 0; i < 100; i++){ pool.addTask(new SimpleTask(new MyManager(), i)); //SimpleTask实现了Task接口 } pool.shutdown(); } } 可以看出用户的使用非常简单 在jdk5中 java提供了线程池 有时间再写一个jdk5的线程池的例子 有一点注意 千万不要在servlet中调用线程池 因为servlet本来就是一个线程池 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-07-24
LZ的思路,是线程共享任务队列,线程按同步方法获取一个非空的任务执行:工作线程自己去“拉单”干。
我提供另外一种思路,线程是被动,由别人(监工)分配,激发: 有一个主线程--“监工”:负责查看任务队列中是否有任务,如果有,取出一个任务,设置到一个“空闲”的线程中,并notify该线程。 while (hasTask) { 1、get the task from task quene 2、get an waiting worker thread, or create a new workder thread 3、set the task to the thread, and set the thread status running synchronized(thread) { 4、thread.nofity();//not notifyAll() } } 线程类的run方法会是这样的: synchronized(this) { while (!shutdown) { if (status == running) { 1、run the task; 2、task = null; 3、status = waiting; 4、manager.done(this, task);//告知监工自己已经完成这个任务 } 5、this.wait(); } } |
|
返回顶楼 | |
发表时间:2007-07-24
ls这种方式倒是比较独特 用另外一种思路解决这个问题
|
|
返回顶楼 | |