在很多的应用场景,需要根据任务去创建线程去异步处理问题,不过不停的创建线程和销毁线程本身是一个非常耗时和消耗系统资源的事情,所以通常这种情况使用线程池来实现,常用的场景比如web容器对于web请求的处理,就是使用的线程池。线程池有几个关键性的元素:

  (1) 工作者线程,比如我们称为workers,负责需要处理的任务

  (2) 任务,比如我们称为Job,也就是需要处理的工作,通过线程池加入BlockingQueue中,然后由线程池的Job分配算法来分配给某一个worker(工作线程)

  (3) 线程池本身,包括线程池的初始化,以及Job的分配工作,复杂一些的包括动态的worker增减算法,在我们的简单示例里面只实现最基本的线程工作。

  实现的Java代码如下:

  

public class ThreadPool{
private static ThreadPool instance = new ThreadPool();
private BlockingQueue<Runnable> jobQueue;
private BlockingQueue<Worker> workers;
private int workerNum;
private ReentrantLock lock = new ReentrantLock(); final class Worker implements Runnable{
Runnable job = null;
public Worker() {
} @Override
public void run() {
// TODO Auto-generated method stub
try {
while ((job = jobQueue.take()) != null) {
job.run();
} } catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static ThreadPool getInstance() {
return instance;
} private ThreadPool() {
workers = new LinkedBlockingQueue<Worker>();
} public void init(int workerNum, BlockingQueue<Runnable> _jobQueue) {
this.workerNum = workerNum;
this.jobQueue = _jobQueue;
} public void execute(Runnable job) {
lock.lock();
try {
if (workers.size() < workerNum) {
Worker worker = new Worker();
Thread t = new Thread(worker);
t.start();
workers.add(worker);
} jobQueue.add(job);
} catch (Exception e) {
// TODO: handle exception
}
finally {
lock.unlock();
}
}
}
 从代码中可以看出ThreadPool代表线程池对象本身,用一个单例实现。其内部类Worker代表工作线程,用来实际处理Job,至于Job,在上面代码里面没有体现,不过jobQueue是一个容纳Runnable接口的队列,我们的Job只需要是一个实现Runnable接口的实例就可以了。BlockingQueue本身是线程安全的,所以Worker中是无需加锁的。不过对worker数量的判断和创建新的线程,需要加锁,防止创建了比设定更多的线程。
  测试代码:
package test;

import java.util.concurrent.LinkedBlockingQueue;

import pool.thread.*;

class TestJob implements Runnable {
int index = 0;
public TestJob(int _index) {
this.index = _index;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("job start " + index + " thread id=" + Thread.currentThread().getId());
}
} public class TestThreadPool { public static void main(String[] args) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
ThreadPool.getInstance().init(10, new LinkedBlockingQueue<Runnable>()); for (int i=0; i<1000; ++i) {
TestJob job = new TestJob(i+1);
ThreadPool.getInstance().execute(job);
} while (true) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} }

  从测试代码可以看出,TestJob这个Job只是简单的实现了Runnable接口。

  不过这个线程池只是为了实现线程池的核心思想,很多需要的功能没有实现,包括针对worker的动态删减,还有针对线程中所有线程的控制,比如中断线程执行等。不过核心的线程池思想还是可以通过上面的代码了解到的。

 

实现简单ThreadPool的更多相关文章

  1. 简单看看ThreadPool的源码以及从中看出线程间传值的另一种方法

    这几天太忙没时间写博客,今天回家就简单的看了下ThreadPool的源码,发现有一个好玩的东西,叫做”执行上下文“,拽名叫做:”ExecutionContext“. 一:ThreadPool的大概流程 ...

  2. ThreadPool.QueueUserWorkItem 简单示例,显示当前时间

    1.线程池  添加方法 作为一个线程运行 class Program { static void Main(string[] args) { ThreadPool.QueueUserWorkItem( ...

  3. C# - 多线程 之 Process与Thread与ThreadPool

    Process 进程类, // 提供对本地和远程进程的访问,启动/停止本地系统进程 public class Process : Component { public int Id { get; } ...

  4. C#多线程--线程池(ThreadPool)

    先引入一下线程池的概念: 百度百科:线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行, ...

  5. 【Quartz】配置最简单的集群

    在许多情况,我们希望我们的定时任务是可靠的,不会因系统故障.机器宕机而导致某一笔定时任务不能按时运行.这种情况下,我们就需要为Quartz做个集群. 最简单的情况,有两台机器或两个应用,同时维护一批定 ...

  6. Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现

    声明:本文为原创博文,转载请注明出处. Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们.在网络编程中,一般都是基于Reactor线程 ...

  7. C++11的简单线程池代码阅读

    这是一个简单的C++11实现的线程池,代码很简单. 原理就是管理一个任务队列和一个工作线程队列. 工作线程不断的从任务队列取任务,然后执行.如果没有任务就等待新任务的到来.添加新任务的时候先添加到任务 ...

  8. Quartz定时任务简单实例

    文章纲要: 初步搭建一个由Quartz为引擎集群的定时任务模块,功能为每隔30秒打印一条信息(Hello World!!!) 一.环境 Spring MVC Mevan Quartz 2.2.1 二. ...

  9. C#基础知识简单梳理

    本文是转发博友的总结,方便自己以后随时温习: 1.值类型和引用类型 1.1堆和栈 简单的说值类型存放在堆栈上面,引用类型的数据存放在托管堆上面(它的引用地址却存放在堆栈上面)! 栈:它是一个内存数组, ...

随机推荐

  1. c# xml的增删改查操作 xmlDocument 的用法

    1.将xml转换为DataTable string path = "";//xml的位置StringReader sr = null;XmlTextReader xmlReader ...

  2. Objective-C( 三、方法的声明与实现)

    OC方法的声明与实现 oc方法的声明在@interface中 大括号外@end上面 oc方法的实现在@implementation 中@end上面 OC方法中,一个参数对应一个冒号 方法名: 例  f ...

  3. 布隆过滤器(Bloom Filter)详解——基于多hash的概率查找思想

    转自:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html   布隆过滤器[1](Bloom Filter)是由布隆(Burton ...

  4. eclipse设置总结

    1.java函数折叠: windows->perferences->General->Editors->Structured Text Editors windows-> ...

  5. PhpStorm WebMatrix xDebug 配置开发环境

    1.首先下载WebMatrix安装程序,下载地址 http://www.microsoft.com/web/webmatrix/  安装步骤 参考:http://www.jb51.net/softjc ...

  6. HTML参考

    HTML Basic Document <html> <head> <title>Document name goes here</title> < ...

  7. 类似github的框架

    github是程序员经常上的网站,但如果是在一家苦逼不能访问外网的公司,那不能把自己的代码托管在github上绝对是一件非常痛苦的事情.如果想要在公司内网也可以用github托管自己的代码,那就要自己 ...

  8. Bootstrap非常简单实用的web前端开发框架

    今天无意间用firebug看网站的代码发现了Bootstrap,之前从来没有听说过这个东东,于是对它产生了好奇感,通过百度我了解到了Bootstrap是一款非常简单,强悍,实用,移动设备端优先使用的这 ...

  9. jenkins持续集成工具

    jenkins是开源的 持续集成.持续构建的可视化web工具,持续构建说直白,就是各种项目的自动化编译.打包.分发部署. 好很多优点: 1.支持多语言 2.跟svn.git能无缝集成 3.直接与知名源 ...

  10. 转 Learning To Rank之LambdaMART的前世今生

    http://blog.csdn.net/huagong_adu/article/details/40710305