java定時器+多線程(池)+java隊列的簡單小例子

需求:每1分鐘去一個表裏查詢list數據並放入java的queue隊列裏(不是MQ,就是一個java隊列)。

     然後喚起線程池,啓動10個線程來取出queue裏的數據並打印出來。

     eg:http://www.it165.net/pro/html/201307/6391.html

1.web.xml
<listener>
   <listener-class>com.sf.partner.mgt.context.APIListener</listener-class>
</listener>
2.APIListener.java
public class APIListener extends HttpServlet implements ServletContextListener {
   private static final long serialVersionUID = 4401296288922971302L;
   public APIListener() {
   }
   private java.util.Timer timer = null;//定義一個定時器
   public void contextInitialized(ServletContextEvent event) {
       timer = new java.util.Timer(true);
           //TaskQuery自定義定時器,查詢list並放入queue隊列裏
       timer.schedule(new TaskQuery(event.getServletContext()), 
               0, 60*1000);// 1000毫秒*60=1分鐘
       event.getServletContext().log("已經添加任務調度表-定時器");
   }

   public void contextDestroyed(ServletContextEvent event) {
       timer.cancel();
       event.getServletContext().log("定時器銷燬");
   }

}
3.TaskQuery.java 
public class TaskQuery extends TimerTask {
   public static Queue<Object> queue;//Queue是java自己的隊列,具體可看API,是同步安全的
   static {
     queue = new ConcurrentLinkedQueue<Object>();
   }
   private static boolean isRunning = false;
   private ServletContext context = null;
   public TaskQuery() {
   }

   public TaskQuery(ServletContext context) {
       this.context = context;
   }
   public void run() {
       if (!isRunning) {
           isRunning = true;
           context.log("開始執行查詢並放入queue隊列");
           queryList();
           context.log("查詢並放入queue隊列結束");
           ThreadPool.createThreadPool();//喚起線程池
           isRunning = false;
       } else {
           context.log("上一次任務執行還未結束");
       }
   }
     /*
   *queue 和 這個queryList()方法都可以根據具體業務提取成單獨的java文件
   */
     public void queryList() {
    //list就是從數據庫裏查詢的結果
     for(String str : list) {
             queue.offer(str);//向隊列添加數據
     }
   } 
}
4.ThreadPool.java
public class ThreadPool {
   public static void createThreadPool() {
       Random random = new Random();
       /**
        * 產生一個 ExecutorService 對象,這個對象帶有一個大小爲 poolSize 的線程池, 若任 務數量大於 poolSize,任務會被放在一個 queue 裏順序執行。這裏開啓10個線程對象,放入線程池
        */
       ExecutorService executor = Executors.newFixedThreadPool(10);
       int waitTime = 500;
       if (TaskQuery.queue.size() > 0) {
   //這個for循環裏的代碼就是從線程池裏獲得線程對象,並執行多線程操作 www.it165.net
        for (int i = 0; i < TaskQuery.queue.size() + 2; i++) {
           int time = random.nextInt(1000);
           waitTime += time;
           Runnable runner = new ExecutorThread(TaskQuery.queue.poll(),
            time);
           executor.execute(runner);
         }
       }
       try {
         Thread.sleep(waitTime);
         executor.shutdown();// 只是將線程池置於關閉狀態,不接受新任務,對正在運行的任務不影響
         executor.awaitTermination(waitTime, TimeUnit.MILLISECONDS);
       } catch (InterruptedException ignored) {
       }
   }
}
/*
*線程類實現Runnable接口
*/
class ExecutorThread implements Runnable {
   private Object obj;
   private int delay;

   public ExecutorThread(Object obj, int delay) {
       this.obj = obj;
       this.delay = delay;
   }

   public void run() {
          /*
       *這裏就是線程需要處理的業務了,可以換成自己的業務
       */
       try {
       if(obj != null) {
        System.out.println("運行的線程數"+Thread.activeCount());
        System.out.println((obj.toString());
       }
           Thread.sleep(delay);
       } catch (InterruptedException ignored) {
       }
   }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章