线程池的使用

一、要点

  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线程池及线程池的如何使用

 



posted @ 2018-08-21 12:58  hcha0  阅读(175)  评论(0编辑  收藏  举报