本章主要记录讲解并发线程的线程池。使用Executor框架自定义线程池。
自定义线程池使用Queue队列所表示出来的形式:
1 ArrayBlockingQueue<Runnable>(3); 有界队列: 2 3 /** 4 * 在使用有界队列时,若有新的任务需要执行,如果线程池实际线程数小于corePoolSize,则优先创建线程, 5 * 若大于corePoolSize,则会将任务加入队列, 6 * 若队列已满,则在总线程数不大于maximumPoolSize的前提下,创建新的线程, 7 * 若线程数大于maximumPoolSize,则执行拒绝策略。或其他自定义方式。 8 */ 9 10 11 12 LinkedBlockingQueue(); 无界队列: 13 14 /** 15 16 *当使用无界队列时,MaxSize则无效,只根据corePoolSize大小来创建线程 17 18 */
Executor自定义异常:
自定义异常类并实现RejectedExecutionHandler类
代码分解:
1 public class MyRejected implements RejectedExecutionHandler{ 2 3 4 public MyRejected(){ 5 } 6 7 @Override 8 public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { 9 System.out.println("自定义处理.."); 10 System.out.println("当前被拒绝任务为:" + r.toString()); 11 } 12 13 }
自定义异常代码解析:
MyTask类实现 Runnable:
1 public class MyTask implements Runnable { 2 3 private int taskId; 4 private String taskName; 5 6 public MyTask(int taskId, String taskName){ 7 this.taskId = taskId; 8 this.taskName = taskName; 9 } 10 11 public int getTaskId() { 12 return taskId; 13 } 14 15 public void setTaskId(int taskId) { 16 this.taskId = taskId; 17 } 18 19 public String getTaskName() { 20 return taskName; 21 } 22 23 public void setTaskName(String taskName) { 24 this.taskName = taskName; 25 } 26 27 @Override 28 public void run() { 29 try { 30 System.out.println("run taskId =" + this.taskId); 31 Thread.sleep(5*1000); 32 //System.out.println("end taskId =" + this.taskId); 33 } catch (InterruptedException e) { 34 e.printStackTrace(); 35 } 36 } 37 38 public String toString(){ 39 return Integer.toString(this.taskId); 40 } 41 42 }
UseThreadPoolExecutor自定义线程池类:
1 public class UseThreadPoolExecutor{ 2 3 4 public static void main(String[] args) { 5 /** 6 * 在使用有界队列时,若有新的任务需要执行,如果线程池实际线程数小于corePoolSize,则优先创建线程, 7 * 若大于corePoolSize,则会将任务加入队列, 8 * 若队列已满,则在总线程数不大于maximumPoolSize的前提下,创建新的线程, 9 * 若线程数大于maximumPoolSize,则执行拒绝策略。或其他自定义方式。 10 * 11 */ 12 ThreadPoolExecutor pool = new ThreadPoolExecutor( 13 1, //coreSize 14 2, //MaxSize 15 60, //60 16 TimeUnit.SECONDS, 17 new ArrayBlockingQueue<Runnable>(3) //指定一种队列 (有界队列) 18 //new LinkedBlockingQueue<Runnable>() 19 , new MyRejected() 20 //, new DiscardOldestPolicy() 21 ); 22 23 MyTask mt1 = new MyTask(1, "任务1"); 24 MyTask mt2 = new MyTask(2, "任务2"); 25 MyTask mt3 = new MyTask(3, "任务3"); 26 MyTask mt4 = new MyTask(4, "任务4"); 27 MyTask mt5 = new MyTask(5, "任务5"); 28 MyTask mt6 = new MyTask(6, "任务6"); 29 30 pool.execute(mt1); 31 pool.execute(mt2); 32 pool.execute(mt3); 33 pool.execute(mt4); 34 pool.execute(mt5); 35 pool.execute(mt6); 36 37 pool.shutdown(); 38 39 } 40 }