池的概念在任何计算机语言中是一个非常重要的思想,任何事情都是有因果的,没有无缘无故的技术,总是为了解决什么问题而出现的。
池的概念就是为了解决资源有限而需求无限的问题。人总是贪婪的,所以总是想占有最多最好的资源,但是人是社会性的,所以需要跟大伙共享一些公共资源,那如何解决这个资源分配的问题呢?
首先资源分配总的原则应该是公平合理高效。翻开经济学的定义,
经济学是一个社会如何利用稀缺的资源生产有价值的物品和劳务,并将它们在不同的人中间进行分配。
[size=large][b]为什么[/b][/size]
回到线程池,首先,为什么线程是有限资源?
第一线程可以很多,为什么有很多,因为要同时做两件事情嘛,而且做一件事情的时候可能需要等待的时间或者在多核CPU的情况下,因此为了不浪费时间或者为了充分利用多核的硬件,我们就在提出了多线程的概念。
那为什么线程的多少有限呢?应该说java里面线程可以随便创建,关键是创建需要时间,销毁也相当耗时间,就像我要吃饭这个事情,非要让我在去吃饭的路上花很多时间一样,完全喧宾夺主啊。
因此我们把这些公共的创建线程,销毁线程的动作放在一个池里面,让池来预先帮我们做好这些事情,这样不就大大提高了执行的效率了吗?
而且这种集中式的管理,对于监控带来了极大的优点。这就是小动作大力量啊。
[size=large][b]怎么做[/b][/size]
首先,我们需要一个池,我叫它ThreadPool
其次,需要线程,我叫它WorkThread
其它的就是一些增强的功能,比如我定义的Tracker用来监控每个任务执行的情况和ThreadPoolContainer用来包含和组织这些动作。
核心代码如下:
ThreadPool
WorkThread
CommandTracker
[size=large][b]To Be Continue...[/b][/size]
目前还未对线程池里面每个线程的优先启用算法进行编写,而是采用了Queue的FIFO的模式
也就是说最先加入free队列的最先被启用。当线程池满的时候,任务会加入到线程是的waiting队列,此时优先级是LIFO,即最近需要加入free队列的线程最先被启用。
下一步需要考虑优先级可以为最少分配任务的那个线程做处理或者任务预分配。因为在WorkThread里面有个执行队列,因此在每个WorkThread里面设置一个阀值,允许一次加入的最大任务数。
池的概念就是为了解决资源有限而需求无限的问题。人总是贪婪的,所以总是想占有最多最好的资源,但是人是社会性的,所以需要跟大伙共享一些公共资源,那如何解决这个资源分配的问题呢?
首先资源分配总的原则应该是公平合理高效。翻开经济学的定义,
经济学是一个社会如何利用稀缺的资源生产有价值的物品和劳务,并将它们在不同的人中间进行分配。
[size=large][b]为什么[/b][/size]
回到线程池,首先,为什么线程是有限资源?
第一线程可以很多,为什么有很多,因为要同时做两件事情嘛,而且做一件事情的时候可能需要等待的时间或者在多核CPU的情况下,因此为了不浪费时间或者为了充分利用多核的硬件,我们就在提出了多线程的概念。
那为什么线程的多少有限呢?应该说java里面线程可以随便创建,关键是创建需要时间,销毁也相当耗时间,就像我要吃饭这个事情,非要让我在去吃饭的路上花很多时间一样,完全喧宾夺主啊。
因此我们把这些公共的创建线程,销毁线程的动作放在一个池里面,让池来预先帮我们做好这些事情,这样不就大大提高了执行的效率了吗?
而且这种集中式的管理,对于监控带来了极大的优点。这就是小动作大力量啊。
[size=large][b]怎么做[/b][/size]
首先,我们需要一个池,我叫它ThreadPool
其次,需要线程,我叫它WorkThread
其它的就是一些增强的功能,比如我定义的Tracker用来监控每个任务执行的情况和ThreadPoolContainer用来包含和组织这些动作。
核心代码如下:
ThreadPool
private static ArrayList<WorkThread> allThreads=new ArrayList<WorkThread>();
private LinkedBlockingQueue<WorkThread> freeThreads=new LinkedBlockingQueue<WorkThread>();
public synchronized boolean notifyOnNewTask(Runnable cmd) {
WorkThread temp=null;
while((temp=freeThreads.poll())!=null){
if(temp.canWork()){
temp.addTask(cmd);
return true;
}//if not free, go to next thread
}
while(allThreads.size()<maxSize){
WorkThread thread=new WorkThread(this,groupName+allThreads.size(),isDaemon);
allThreads.add(thread);
thread.start();
if(thread.canWork()){
thread.addTask(cmd);
return true;
}
}
waitingQueue.add(cmd);
return false;
}
//free a thread
public synchronized void addToFreeList(WorkThread workThread) {
Runnable cmd=waitingQueue.poll();
if(cmd!=null){//no need to add to free list, who is free, who will do the job.
workThread.addTask(cmd);
return;
}
if(!freeThreads.contains(workThread)){
freeThreads.add(workThread);
}
}
WorkThread
public void run() {
while (isUp) {
isFree.set(true);
m_pool.addToFreeList(this);
try {
Runnable o=queue.poll(10000, TimeUnit.MILLISECONDS);
if(o==null){
if(isUp==false){
return;
}
continue;
}
isFree.set(false);
o.run();
} catch (InterruptedException e1) {
e1.printStackTrace();
}// wait
}
}
CommandTracker
public void oneIsDone(WrappingCommandTask task) {
m_counter.decrementAndGet();
synchronized (this) {
if (m_counter.decrementAndGet() == 0) {
// signal
notify();
}
}
}
public boolean isAllDone() {
return m_counter.get() ==0;
}
[size=large][b]To Be Continue...[/b][/size]
目前还未对线程池里面每个线程的优先启用算法进行编写,而是采用了Queue的FIFO的模式
也就是说最先加入free队列的最先被启用。当线程池满的时候,任务会加入到线程是的waiting队列,此时优先级是LIFO,即最近需要加入free队列的线程最先被启用。
下一步需要考虑优先级可以为最少分配任务的那个线程做处理或者任务预分配。因为在WorkThread里面有个执行队列,因此在每个WorkThread里面设置一个阀值,允许一次加入的最大任务数。