java架构《并发线程高级篇二》

    本章主要记录讲解并发线程的线程池。使用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       }