什么 是线程池?
线程池是一种多线程的处理方式。简单地说可以理解成一个放着多个线程的池子,把你要执行的任务放进来,它会自己进行调优,分配,统一管理执行。
为什么 需要线程池?
1。在面向对象的编程里,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。当然为这个是消耗时间是相对要执行的任务来说。假设创建执行对象 的时间为T1,要执行任务的时间为T2,销毁执行对象的时间为T3。在T3+T1远大于T2的情况下,就要考虑是否应该减少执行对象的创建。
2。我们说无论是什么 东西都是一个限度的,JAVA虚拟机提供的空间也一样。比如说,像我们对一个网页请求(比较大的算是BAIDU)好了,按平时的做法,同时并发时可能每秒都会产生超多个线程请求,如果说一下子要创建出超多个线程来执行请求,那可能虚拟机就会当掉啦!所以对于线程的统一管理调度还是相当重要的。。
3。综上所述,线程池的好处是:1)降低资源消耗。通过重复利用创建的线程,减少创建和销毁线程对象的过程。2)提高任务执行响应速度,可以不用等待线程创建就立即执行(当然这里说的是线程池内还没有闲置线程的情况下)3)提高线程的可管理性。通过线程池对线程进行统一的管理,调优,分配。
简单样例实现
package com.mythread;
import java.util.Vector;
/**
* 自己实现的一个简单的线程池
*/
public class MyThreadPool {
/**
* 默认的线程池大小
*/
private static final int DEFAULT_SIZE = 10;
/**
* 任务队列
*/
private Vector<Runnable> taskQueue;
/**
* 工作的线程们
*/
private Thread[] workThreads;
/**
* 标记线程池是否关闭
*/
private boolean closed;
/**
* @return the closed
*/
public boolean isClosed() {
return closed;
}
/**
* @param closed
* the closed to set
*/
public void setClosed() {
// 如果已经关闭过了就不做其它操作了
if (closed) {
return;
}
// 设置为已经关闭
this.closed = true;
// 清除任务队列
taskQueue.clear();
// 等待当前要完成的线程完成工作
waitfinish();
// 让所有的线程醒过来
notifyAll();
}
/**
* 让线程JOIN,等待完成
*/
private void waitfinish() {
for (Thread thread : workThreads) {
if (thread.isAlive()) {
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 指定要生成线程池中设置工作线程的数量
*
* @param queueSize
*/
public MyThreadPool(int queueSize) {
taskQueue = new Vector<Runnable>();
workThreads = new Thread[queueSize];
// 生成工作线程,并且启动
for (int i = 0; i < queueSize; i++) {
workThreads[i] = new Worker(i);
workThreads[i].start();
}
}
/**
* 每加入一个任务,注意要唤醒一个工作线程
*
* @param task
*/
public synchronized void addTask(Runnable task) {
taskQueue.add(task);
notify();
}
/**
* 获取任务
*
* @param id
* 要工作的线程的ID
* @return
* @throws InterruptedException
*/
public synchronized Runnable getTask(int id) throws InterruptedException {
if (closed) {
throw new RuntimeException("The pool has closed!");
}
// 当没有任务时等待
while (taskQueue.isEmpty()) {
// 如果线程池已经关闭了,可以返回了
if (isClosed()) {
return null;
}
System.out.println(id + " is waiting~");
wait();
}
System.out.println(id + " start to work!");
// 返回一个要执行的任务
return taskQueue.remove(0);
}
public MyThreadPool() {
this(DEFAULT_SIZE);
}
/**
* 要给线程池打工的线程
*/
private class Worker extends Thread {
/**
* 线程的ID
*/
private int id;
public Worker(int id) {
super();
this.id = id;
}
@Override
public void run() {
// 线程工人是一个很苦逼的工人。。从一出生就要去看是有没有任务要执行。。直到线程池关闭。。
while (!isClosed()) {
Runnable task = null;
try {
task = getTask(id);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (task != null) {
task.run();
}
}
}
}
}