线程池的使用
一、要点
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+"执行完毕"); } }
示例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); } } }
三、资料引用: