1700450667
1700450668
}
1700450669
1700450670
//从任务队列中获得任务
1700450671
1700450672
Runnable getTask(){
1700450673
1700450674
for(;){
1700450675
1700450676
return workQueue.take();
1700450677
1700450678
}
1700450679
1700450680
}
1700450681
1700450682
此处为示意代码,删除了大量的判断条件和锁资源。execute方法是通过Worker类启动的一个工作线程,执行的是我们的第一个任务,然后该线程通过getTask方法从任务队列中获取任务,之后再继续执行,但问题是任务队列是一个BlockingQueue,是阻塞式的,也就是说如果该队列元素为0,则保持等待状态,直到有任务进入为止,我们来看LinkedBlockingQueue的take方法,代码如下:
1700450683
1700450684
public E take()throws InterruptedException{
1700450685
1700450686
//如果队列中元素数量为0,则等待
1700450687
1700450688
while(count.get()==0)
1700450689
1700450690
notEmpty.await();
1700450691
1700450692
//等待状态结束,弹出头元素
1700450693
1700450694
x=extract();
1700450695
1700450696
//如果队列数量还多于1个,唤醒其他线程
1700450697
1700450698
if(c>1)
1700450699
1700450700
}
1700450701
1700450702
notEmpty.signal();
1700450703
1700450704
//返回头元素
1700450705
1700450706
return x;
1700450707
1700450708
}
1700450709
1700450710
分析到这里,我们就明白了线程池的创建过程:创建一个阻塞队列以容纳任务,在第一次执行任务时创建足够多的线程(不超过许可线程数),并处理任务,之后每个工作线程自行从任务队列中获得任务,直到任务队列中的任务数量为0为止,此时,线程将处于等待状态,一旦有任务再加入到队列中,即唤醒工作线程进行处理,实现线程的可复用性。
1700450711
1700450712
使用线程池减少的是线程的创建和销毁时间,这对于多线程应用来说非常有帮助,比如我们最常用的Servlet容器,每次请求处理的都是一个线程,如果不采用线程池技术,每次请求都会重新创建一个线程,这会导致系统的性能负荷加大,响应效率下降,降低了系统的友好性。
1700450713
1700450714
1700450715
1700450716
[
上一页 ]
[ :1.700450667e+09 ]
[
下一页 ]