Java线程池的创建
线程池(Thread Pool)的概念来自于实际需要,其主要应用在网络环境下服务器端程序的设计。
- 通常一个服务器程序的设计模型是:当客户有请求到达时,服务器就创建一个新线程,由该线程为客户端提供服务。但是这种设计的缺陷在于:为每一个请求创建一个线程的开销很大,而且服务器在创建和销毁线程上所花费的时间和消耗的系统资源要比处理用户请求的时间和资源更多。所导致的后果是Java虚拟机创建太多的线程会导致系统内存耗尽;为防止这种资源不足情况的发生,服务器端需要一种机制来限制线程的创建,这样就应用到线程池。
线程池机制是先创建一些线程等待服务器端程序的调用,这些线程保存在一个数组结构中,称为“线程池”。当服务器有任务执行时,就从线程池中取一个空闲的线程并分配其任务,当线程任务执行完毕再被放回到线程池中。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。
线程池带来的好处是:请求到达时线程已经存在,消除了线程创建所带来的开销和时间,可以立即为请求服务,使程序响应更快;通过适当的调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其他任何新到的请求一直等待,直到获得一个线程来处理为止,从而可防止资源不足。
- 当然java的线程池的核心是java.uitl.concurrent.ThreadPoolExecutor;这个网上已经有一大堆了,
参考:[http://www.cnblogs.com/dolphin0520/p/3932921.html],这里讲的非常详细了。我这里不细说,只写个例子如何设计一个线程池和它的工作原理。
import java.util.LinkedList;
public class ThreadPool {
private final int nThreads = 10;//线程池中线程的最大值
private final WorkThread[] threads;//线程数组
private final LinkedList<Runnable> queue;//线程要处理的任务队列
public ThreadPool() {
queue = new LinkedList<Runnable>();
threads = new WorkThread[nThreads];
for (int i = 0; i < nThreads; i++) {
threads[i] = new WorkThread();
threads[i].start();
}
}
/**
* 将任务加入任务队列的方法
* @param r
*/
public void excute(Runnable r) {
synchronized (queue) {
queue.add(r);
queue.notify();
}
}
/**
* 线程的执行
*/
private class WorkThread extends Thread {
public void run() {
Runnable r;
while (true) {
synchronized (queue) {
while (queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
r = (Runnable) queue.removeFirst();
}
try{
r.run();
}catch(RuntimeException e){
System.out.println(e);
}
}
}
}
}
测试类
public class Test {
static int j = 0;
public static void main(String[] args) {
ThreadPool tp = new ThreadPool();
for (int i = 0; i < 100; i++) {
tp.excute(new Runnable() {
public void run() {
System.out.println(++j);
}
});
}
}
}
上列中利用构造方法创建一个线程池,当我们把任务通过excute方法加入到任务队列中;线程组中每个线程需要判断当前任务队列中是否有任务需要处理,若有则取出并执行;否则进入等待状态。