zoukankan      html  css  js  c++  java
  • 多线程编程(五)--线程池

              JDK 1.5之后增加了Java.util.concurrent包。这个包中主要介绍java中线程以及线程池的使用。为我们在开发中处理线程的问题提供了很大的帮助。

     

    一、池的由来

            拿数据库来举样例:每当一个请求到达就创建一个新的链接,但当有大量请求并发訪问时。就会不断地创建和销毁链接,开销非常大。为了提高效率,达到复用的效果,就有了池的概念。

            线程池是预先创建线程的一种技术。

    线程池在任务还没到来之前先创建一定数量的线程。放入空暇队列中。这些线程都是处于睡眠状态。即均为启动,不消耗CPU,而仅仅是占用较小的内存空间。当请求到来之后。缓冲池给这次请求分配一个空暇线程,把请求传入此线程中执行,进行处理。当预先创建的线程都处于执行状态。即预制线程不够,线程池能够自由创建一定数量的新线程,用于处理很多其它的请求。当系统比較闲的时候,也能够通过移除一部分一直处于停用状态的线程。

     

    二、使用线程池的优点

             1、降低了创建和销毁线程的次数。达到最大程度的复用对象

              2、线程代码和业务代码分离

     

    三、线程池使用

             Java里面线程池的顶级接口是Executor,可是严格意义上讲Executor并非一个线程池,而仅仅是一个运行线程的工具。

    真正的线程池接口是ExecutorService

     

    1、固定线程池

    ExecutorServicethreadPool = Executors.newFixedThreadPool(3);// 创建能够容纳3个线程的线程池 

     

    2、缓存的线程池

    ExecutorServicethreadPool = Executors.newCachedThreadPool();// 线程池的大小会依据运行的任务数动态分配 

     

    3、单一线程池

    ExecutorServicethreadPool = Executors.newSingleThreadExecutor();
    //池子里面仅仅有一个线程,优点是假设池子里面的线程死掉,它会再启动一个线程所以实现了线程死后重新启动一个线程


     

    代码:

    public static voidmain(String[] args) {
    //固定的线程池
    ExecutorServicethreadPool = Executors.newFixedThreadPool(3);
     
    //缓存的线程池
    //                ExecutorServicethreadPool = Executors.newCachedThreadPool();
     
    //池子里面仅仅有一个线程,优点是假设池子里面的线程死掉。它会再启动一个线程所以实现了线程死后重新启动一个线程
    //                ExecutorServicethreadPool = Executors.newSingleThreadExecutor();
     
    for(int i = 1; i <= 10; i++) {
    finalint task = i;
    threadPool.execute(newRunnable() {
    @Override
    publicvoid run() {
    for(int j = 1; j < 10; j++) {
    try{
    Thread.sleep(20);
    }catch (InterruptedException e) {
    //TODO Auto-generated catch block
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()
    +" is looping of " + j + " for task of " + task);
    }
    }
    });
    }
    System.out.println("allof 10 task have committed! ");
    //6s以后炸。每隔2S炸一下
    Executors.newScheduledThreadPool(3).scheduleAtFixedRate(newRunnable(){
    @Override
    publicvoid run() {
    System.out.println("bombing");
     
     
    }
    }, 6,2, TimeUnit.SECONDS);  //6s以后炸。每隔2S炸一下
    }
     
    }

     

    执行效果:

    固定线程:

                   

            当前设置了三个线程,故这三个线程在工作。FixedThreadPool中,有一个固定大小的池,假设当前须要运行的任务超过了池大小。那么多余的任务等待状态,直到有空暇下来的线程运行任务,而当运行的任务小于池大小,空暇的线程也不会去销毁。假设某个线程由于运行异常而结束,那么线程池会补充一个新线程。

     

    缓存线程:

                  

             这几个线程是交替工作的,CachedThreadPool会创建一个缓存区。将初始化的线程缓存起来。假设线程池的大小超过了处理任务所须要的线程。那么就会回收部分空暇(60秒不运行任务)的线程,当任务数添加时,此线程池又可以智能加入新线程来处理任务。

    此线程池也不会对线程池大小做限制,线程池大小全然依赖于操作系统(或者说JVM)可以创建的最大线程大小。


    单个线程池

                  

           仅仅有一个线程在工作。

    此线程池保证全部任务的运行顺序依照任务的提交顺序运行。

  • 相关阅读:
    drf—— 序列化组件
    drf—— RESTful API规范
    drf——APIView及其内部函数/类的源码分析
    drf—— drf的安装和使用
    226翻转二叉树
    51,N皇后
    557反转字符串中的单词III
    17.电话号码的字母组合
    459重复的子字符串
    419递增子序列
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/6866146.html
Copyright © 2011-2022 走看看