• 线程池的使用


    一、要点

      1. public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,

                BlockingQueue<Runnable> workQueue);

          corePoolSize:核心池的大小,初始化线程的数量

         maximumPoolSize:线程池最大线程数

         keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。

         unit:参数keepAliveTime的时间单位,有7种取值

    TimeUnit.DAYS;               //
    TimeUnit.HOURS;             //小时
    TimeUnit.MINUTES;           //分钟
    TimeUnit.SECONDS;           //
    TimeUnit.MILLISECONDS;      //毫秒
    TimeUnit.MICROSECONDS;      //微妙
    TimeUnit.NANOSECONDS;       //纳秒

        workQueue:一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响

       workQueue的类型为BlockingQueue<Runnable>,通常可以取下面三种类型:

      1)ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小;

      2)LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;

      3)synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。

    ArrayBlockingQueue;
    LinkedBlockingQueue;
    SynchronousQueue;

         

      2、ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown()和shutdownNow(),其中:

    • shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
    • shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务

      3、executor.allowCoreThreadTimeOut(true);  //在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;

      4、当前线程阻塞,直到等所有已提交的任务(包括正在跑的和队列中等待的)执行完

           或者等超时时间到或者线程被中断,抛出InterruptedException

          然后返回true(shutdown请求后所有任务执行完毕)或false(已超时)

    //判断所有任务是否完成
    while
    (!executor.awaitTermination(2, TimeUnit.SECONDS)) { System.out.println("executor not stop!!!"); }

    二、示例:

       示例1

    public class Test {
         public static void main(String[] args) {   
             ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
                     new ArrayBlockingQueue<Runnable>(5));
              
             for(int i=0;i<15;i++){
                 MyTask myTask = new MyTask(i);
                 executor.execute(myTask);
                 System.out.println("线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
                 executor.getQueue().size()+",已执行玩别的任务数目:"+executor.getCompletedTaskCount());
             }
             executor.shutdown();
         }
    }
     
     
    class MyTask implements Runnable {
        private int taskNum;
         
        public MyTask(int num) {
            this.taskNum = num;
        }
         
        @Override
        public void run() {
            System.out.println("正在执行task "+taskNum);
            try {
                Thread.currentThread().sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task "+taskNum+"执行完毕");
        }
    }
    View Code

       示例2

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.CopyOnWriteArrayList;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    public class IPTelnetTaskTread {
        public static Connection conn = null;
        public static PreparedStatement ps = null;
        public static List<String> yip = new CopyOnWriteArrayList<String>();
        static {
            try {
                conn = ConnUtil.dbConn();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        public static void main(String[] args) throws Exception {
            IPTelnetTaskTread tread=new IPTelnetTaskTread();
            tread.execute();
        }
        
        public void execute() throws Exception{
            String Sql = "";
            Sql= "SELECT ip FROM ipinfo where status !=1 ";
            ps = conn.prepareStatement(Sql);
            ResultSet rs = ps.executeQuery();
            List<String> ipl = new ArrayList<String>();
            while (rs.next()) {
                ipl.add(rs.getString(1));
            }
            
            ThreadPoolExecutor executor = new ThreadPoolExecutor(360000, 400000,
                    200, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(360000));
            executor.allowCoreThreadTimeOut(true);  //在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;
            for (int i = 0; i < ipl.size(); i++) {
                MyTask myTask = new MyTask(ipl.get(i),i);
                executor.execute(myTask);   //执行线程任务
                System.out.println("线程池中线程数目:" + executor.getPoolSize()
                        + ",队列中等待执行的任务数目:" + executor.getQueue().size()
                        + ",已执行玩别的任务数目:" + executor.getCompletedTaskCount());
            }
            
            executor.shutdown(); 
    //判断线程池任务是否结束,因为线程任务是异步执行 需要阻止下面的程序的执行
    while (!executor.awaitTermination(2, TimeUnit.SECONDS)) { System.out.println("executor not stop!!!"); } System.err.println("yip.size():" + yip.size()); ps = conn.prepareStatement("update ipinfo set status=1 where ip=? "); for (int i = 0; i < yip.size(); i++) { ps.setString(1, yip.get(i)); ps.addBatch(); } ps.executeBatch(); ps.close(); conn.close(); } class MyTask implements Runnable { private String tasks; private int i; public MyTask(String tasks,int i) { this.tasks = tasks; this.i=i; } @Override public void run() { System.out.println("正在执行task " + tasks); /*任务*/ IPTelnetTaskTread.yip.add(tasks); System.err.println("执行结束..."+tasks+"---"+i); } } }

    三、资料引用:

      1、Java并发编程:线程池的使用

      2、由浅入深理解Java线程池及线程池的如何使用

     



  • 相关阅读:
    stm32之PWM博客好文收藏
    CSDN怎么转载别人的博客
    STM32F103单片机学习—— 通用定时器
    STM32 通用定时器好文章收藏
    stm32基本定时器timer6的原理与使用
    freertos优秀博客收藏
    StretchBlt函数和BitBlt函数的用法
    对话框添加背景图片
    vc 使窗口置顶 在最前面
    CWnd::MoveWindow 详解
  • 原文地址:https://www.cnblogs.com/Dream2hc/p/java754497.html
Copyright © 2020-2023  润新知