java中的线程池主要是用来处理多线程的请求并处理的。举个例子:比如,现在有4个线程为多个请求提供服务,那么一次最多只能有4个请求得到响应,这4个线程就为其中的4个请求服务,而处理这4个请求可能会浪费很多的时间,而其它的请求在干等着,等这4个线程空闲出来才能为为其它的请求提供服务。如下图:
那么如果请求很多,那么这样的处理就会很浪费时间。
java中的线程池(队列)可以很好的解决这样的额问题,如下图:
每个线程将接待(响应)的请求放到线程池中,这样其实就是每一个接待的线程只负责接待(响应),将其放到线程池,不管其具体是怎么处理的,而让专门处理的线程在线程池中取出请求,并处理。这样对于每一个请求,都不会等待太多的时间,就可以得到响应。提高的运行的效率。(有点类似于计算机中的流水线处理)
下面用代码演示一下线程池的应用。
- 1-1 一个线程池的例子
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.TimeUnit;
- public class ThreadPoolTest {
- public static void main(String[] args) {
- ExecutorService threadPool = Executors.newFixedThreadPool(3);//线程池,3个线程处理池子中的任务。是固定的线程池
- //线程池,是缓存的线程池,当请求多时,内部自动增加新的线程,它内部的线程个数是不定的
- //ExecutorService threadPool = Executors.newCachedThreadPool();
- //线程池中只有一个线程,相当于单线程,没有线程池的概念,但是有一个好处:如果池子中的线程死了,它会自动再找一个线程,
- //保证有一个线程,可以实现线程死了之后自动重新启动
- //ExecutorService threadPool = Executors.newSingleThreadExecutor();
- for(int i=1;i<=10;i++){ //往线程池中扔10个任务
- final int task = i;
- threadPool.execute(new Runnable(){ //每循环一次把一个任务给Runnable()
- @Override
- public void run() {
- for(int j=1;j<=10;j++){ //每个任务循环10遍,打印信息
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName()
- + " is looping of " + j + " for task of " + task);
- }
- }
- });
- }
- System.out.println("all of 10 tasks have committed! ");
- //threadPool.shutdownNow();//立即把线程关闭
- Executors.newScheduledThreadPool(3).scheduleAtFixedRate(//一固定的频率执行某一操作
- new Runnable(){
- @Override
- public void run() {
- System.out.println("bombing!");
- }},
- 6,//多长时间以后打印bombing!
- 2,//每隔多长时间执行的操作
- TimeUnit.SECONDS);//时间单位
- }
- }
程序运行的结果如下:
从运行结果页可以看到:
- ExecutorService threadPool = Executors.newFixedThreadPool(3);
在执行的时候,线程池中始终有3个线程在执行任务。
总结:线程池一般用在开发服务器,比如Tomcat。