Java Design Demo -简单的队列-异步多任务队列(java android)

简单的单线程队列 -- 工作的时候遇到劣质打印机。给打印机发消息,打印机就会打印,如果在打印机还在打印的时候,就

再发消息打印,就会出现消息丢失。所以需要给上一个任务一些处理的间隔时间.

单线程的消息队列示例

 

  1. package demo1;  
  2.   
  3. import java.util.LinkedList;  
  4.   
  5. public class Main {  
  6.   
  7.     /** 
  8.      * @param args 
  9.      */  
  10.   
  11.     private static Thread thread;  
  12.     private static LinkedList<Runnable> list = new LinkedList<Runnable>();  
  13.   
  14.     static int test = 0;  
  15.   
  16.     public static void main(String[] args) {  
  17.         // TODO Auto-generated method stub  
  18.         final long time = System.currentTimeMillis();  
  19.         for (int i = 0; i < 20; i++) {  
  20.   
  21.             tastEvent(new Runnable() {  
  22.                 public void run() {  
  23.   
  24.   
  25.                         try {  
  26.                             Thread.sleep(500);  
  27.                         } catch (InterruptedException e) {  
  28.                             // TODO Auto-generated catch block  
  29.                             e.printStackTrace();  
  30.                         }  
  31.   
  32.                         System.out  
  33.                                 .println("第"  
  34.                                         + (++test)  
  35.                                         + ("个任务  耗时:" + (System  
  36.                                                 .currentTimeMillis() - time)));  
  37.                     }  
  38.   
  39.             });  
  40.         }  
  41.     }  
  42.   
  43.     public static void tastEvent(Runnable r) {  
  44.         synchronized (list) {  
  45.             list.add(r);  
  46.         }  
  47.             if (thread == null) {  
  48.                 thread = new Thread(run);  
  49.                 thread.start();  
  50.             }  
  51.   
  52.   
  53.     }  
  54.   
  55.     static Runnable run = new Runnable() {  
  56.   
  57.         @Override  
  58.         public void run() {  
  59.             // TODO Auto-generated method stub  
  60.             synchronized (list) {  
  61.   
  62.                 while (!list.isEmpty()) {  
  63.                     // new Thread(list.poll()).start();  
  64.                     list.poll().run();  
  65.                 }  
  66.                 thread = null;  
  67.             }  
  68.         }  
  69.     };  
  70.   
  71. }  


 

 

工作的时候遇到非常大的并发的情况,比如机器1秒只支持1000的并发,但是1秒接收了4000的并发。服务器就会崩掉。

最好将并发放到队列中,按1000的并发吞吐量来处理,这就是异步队列应用。

 

一个工程交给一个人做,需要花费3个月,交给2个人做,需要2个人做需要2个月,需要3个人做需要1个月半.....100.人.....1000人,几年也完不成。

带上以上道理看待以下的代码

 

观察以下代码(复制到android工程下运行):最后耗时约1600毫秒 而使用android的AsyncTask类来改写这段代码只需要耗时约200 

 

 

  1. final long  timer=System.currentTimeMillis();  
  2. count=0;  
  3. final Handler h=new Handler();  
  4. for(int k=0;k<100;k++){  
  5. new Thread(){  
  6.     @Override  
  7.     public void run() {  
  8.         // TODO Auto-generated method stub  
  9.         try {  
  10.             Thread.sleep(10);  
  11.         } catch (InterruptedException e) {  
  12.             // TODO Auto-generated catch block  
  13.             e.printStackTrace();  
  14.         }  
  15.         h.post(new Runnable() {  
  16.             @Override  
  17.             public void run() {  
  18.                 Toast.makeText(getApplicationContext()," 耗时"+ (System.currentTimeMillis() - timer), 1).show();  
  19.                 System.err.println("编号"+(count++)+"线程消耗了"+(System.currentTimeMillis()-timer));  
  20.             }  
  21.         });  
  22.     }  
  23. }.start();  



 

 

可见增加多线程不提高性能,反而因为系统在不同的线程之间切换降低效率。因此我们需要让线程有序执行任务

以下是异步多线程处理队列的demo

 

 

  1. package demo2;  
  2.   
  3. import demo2.Task.OnFinishListen;  
  4.   
  5. public class Main {  
  6.   
  7.     /** 
  8.      * @param args 
  9.      */  
  10.     public static void main(String[] args) {  
  11.         // TODO Auto-generated method stub  
  12.           
  13.         Task.setThreadMaxNum(3);  
  14.         for (int i = 0; i < 15; i++) {  
  15.             new Task() {  
  16.   
  17.                 @Override  
  18.                 public Object obtainData(Task task, Object parameter)  
  19.                         throws Exception {  
  20.                     // TODO Auto-generated method stub  
  21.                     Thread.sleep(500);  
  22.                     return task.taskID;  
  23.                 }  
  24.   
  25.             }  
  26.             .setOnFinishListen(new OnFinishListen() {  
  27.   
  28.                 @Override  
  29.                 public void onFinish(Task task, Object data) {  
  30.                     // TODO Auto-generated method stub  
  31.                     System.err.println("任务编号"+task.taskID+"任务完成");  
  32.                 }  
  33.             })  
  34.             .setTaskID(i)  
  35.             .start();  
  36.         }  
  37.     }  
  38.   
  39. }  



 

 

 

  1. package demo2;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. import java.util.Map;  
  6. import java.util.Observable;  
  7. import java.util.Observer;  
  8.   
  9. public abstract class Task<P,R> implements Runnable, Observer,TaskAction<P,R>{  
  10.   
  11.       
  12.   
  13.       
  14.     //设置最大任务数  
  15.     public static void setThreadMaxNum(int num) {  
  16.         TaskQueue.ThreadMaxNum = num<1?1:num>100?100:num;  
  17.     }  
  18.   
  19.       
  20.       
  21.     public static enum TaskPriority {  
  22.         max, min;  
  23.     }  
  24.   
  25.     /** 单例 可以提高性能 */  
  26.     protected final static Exception withoutException = new Exception(  
  27.             "The state is without");  
  28.   
  29.     // 名字映射  
  30.     private static HashMap<String, Task> nameTasks;  
  31.   
  32.     public static HashMap<String, Task> getNameTask() {  
  33.         if (nameTasks == null) {  
  34.             nameTasks = new HashMap<String, Task>();  
  35.         }  
  36.         return nameTasks;  
  37.   
  38.     }  
  39.   
  40.     public Task<P,R> setSingletonName(String singletonName) {  
  41.         this.singletonName = singletonName;  
  42.         return this;  
  43.     }  
  44.   
  45.     public String getSingletonName() {  
  46.         return singletonName;  
  47.     }  
  48.   
  49.     public interface OnStartListen {  
  50.         void onStart(Task t);  
  51.     }  
  52.   
  53.     public interface OnProgressListen {  
  54.         void onProgress(Task task, int progress, Object data);  
  55.     }  
  56.   
  57.     public static interface OnFinishListen<P,R> {  
  58.         void onFinish(Task<P,R> task, R data);  
  59.     }  
  60.   
  61.     public interface OnSystemStartListen {  
  62.         void onSystemStart(Task task);  
  63.     }  
  64.   
  65.     public interface OnSystemFinishListen {  
  66.         void OnSystemFinish(Task t, Object data);  
  67.     }  
  68.   
  69.       
  70.   
  71.     /** 请求参数 */  
  72.     protected P parameter;  
  73.     /** 任务开始监听 */  
  74.     protected OnStartListen onStartListen;  
  75.     /** 任务进度监听 */  
  76.     protected OnProgressListen onProgressListen;  
  77.     /** 任务完成监听 */  
  78.     protected OnFinishListen<P,R> onFinishListen;  
  79.     /** 任务在队列中完成 监听 */  
  80.     protected OnSystemStartListen onSystemStartListen;  
  81.     /** 任务在队列中开始 监听 */  
  82.     protected OnSystemFinishListen onSystemFinishListen;  
  83.     /** 用于任务完成后发送消息 */  
  84.     /** 结果 */  
  85.     protected R result;  
  86.     /** 任务编号标示 */  
  87.     protected int taskID = -1;  
  88.     /** 任务名字标示 */  
  89.     /** 设置此任务名是否为单例,单例模式下,如果相同名字的任务未执行完,则无法添加新任务 */  
  90.     protected String singletonName;  
  91.   
  92.     /** 保存一个对象 */  
  93.     protected Object tag;  
  94.     /** 获得当前自身线程的引用 在threadRun方法 */  
  95.     protected Thread thread;  
  96.     /** 重连次数 */  
  97.     protected int tryAgainCount = 1;  
  98.     /** 重连间隔 */  
  99.     protected int tryAgainTime = 1000;  
  100.   
  101.   
  102.   
  103.     /** 默认优先级低 */  
  104.     protected TaskPriority priority = TaskPriority.min;  
  105.   
  106.   
  107.     protected HashMap<String,Object> dataMap;  
  108.       
  109.   
  110.     protected Task() {  
  111.     }  
  112.   
  113.   
  114.   
  115.     // 任务状态  
  116.     public static enum TaskStatus {  
  117.         // 未处理 出错 完成 执行中 排除  
  118.         untreated, wait,error, finsh, running, without;  
  119.     }  
  120.   
  121.     /** 状态 */  
  122.     TaskStatus status = TaskStatus.untreated;  
  123.   
  124.     public void setWithout() {  
  125.         this.status = TaskStatus.without;  
  126.     }  
  127.   
  128.     public void remove() {  
  129.         this.status = TaskStatus.without;  
  130.     }  
  131.   
  132.     public TaskPriority getPriority() {  
  133.         return priority;  
  134.     }  
  135.   
  136.     public void setPriority(TaskPriority priority) {  
  137.         this.priority = priority;  
  138.     }  
  139.   
  140.   
  141.       
  142.     /** 启动线程 */  
  143.     public void start() {  
  144.         if (this.priority == null)  
  145.             this.priority = TaskPriority.min;  
  146.           
  147.         synchronized (TaskQueue.tasks_wait) {  
  148.             if (getSingletonName() != null  
  149.                     && Task.getNameTask().get(this.getSingletonName()) != null) {  
  150.                 this.setWithout();  
  151.             } else {  
  152.                 Task.getNameTask().put(this.getSingletonName(), this);  
  153.   
  154.             }  
  155.   
  156.             switch (priority) {  
  157.             case min:  
  158.                 TaskQueue.tasks_wait.remove(this);  
  159.                 TaskQueue.tasks_wait.add(this);  
  160.                 break;  
  161.             case max:  
  162.                 TaskQueue.tasks_wait.remove(this);  
  163.                 TaskQueue.tasks_wait.addFirst(this);  
  164.                 break;  
  165.             default:  
  166.                 break;  
  167.             }  
  168.             // 启动此服务  
  169.             TaskQueue.serivesRun();  
  170.         }  
  171.           
  172.     }  
  173.   
  174.     /** 启动线程 */  
  175.     public void start(TaskPriority priority) {  
  176.           
  177.           
  178.         this.priority = priority;  
  179.         status=TaskStatus.wait;  
  180.         start();  
  181.     }  
  182.   
  183.   
  184.     /** 启动线程 */  
  185.     final void threadRun() {  
  186.         thread = new Thread(this);  
  187.         thread.start();  
  188.     }  
  189.   
  190.     // 中断Execute方法  
  191.     public  void shutDownExecute(){};  
  192.   
  193.     public  R cacheData(P parameter){  
  194.         return result;};  
  195.   
  196.     // 禁止被重写  
  197.     public final Object Execute() throws Exception {  
  198.         // TODO Auto-generated method stub  
  199.         if (onStartListen != null)  
  200.             onStartListen.onStart(this);  
  201.   
  202.         // 队列中回调  
  203.         if (onSystemStartListen != null)  
  204.             onSystemStartListen.onSystemStart(this);  
  205.         // 状态从未处理改变为处理中  
  206.         status = TaskStatus.running;  
  207.   
  208.         // 获取最后一次是否错误  
  209.         Exception exception = null;  
  210.         // 是否有缓存数据如果没有  
  211.         if ((result = cacheData(parameter)) == null) {  
  212.   
  213.             // 失败重联次数  
  214.             for (int i = 0; i < tryAgainCount; i++) {  
  215.                 try {  
  216.                     // 如果状态改变为排除则跳出失败重联  
  217.                     if (status == TaskStatus.without) {  
  218.                         break;  
  219.                     }  
  220.                     exception = null;  
  221.                     result = obtainData(this, parameter);  
  222.                     System.out.println("result=" + result);  
  223.                     break;  
  224.                 } catch (Exception e) {  
  225.                     // TODO Auto-generated catch block  
  226.                     if ((exception = e) == withoutException) {  
  227.                         break;  
  228.                     }  
  229.                     e.printStackTrace();  
  230.                     try {  
  231.                         Thread.sleep(tryAgainTime);  
  232.                     } catch (Exception e1) {  
  233.                         // TODO Auto-generated catch block  
  234.                         e1.printStackTrace();  
  235.                     }  
  236.                 }  
  237.             }  
  238.         }  
  239.         // 如果最后一次仍然失败则抛出  
  240.         if (exception != null) {  
  241.             throw exception;  
  242.         }  
  243.   
  244.   
  245.         // 如果状态改变为处理完但不通知  
  246.         if (status != TaskStatus.without) {  
  247.   
  248.             if (onFinishListen != null) {  
  249.                 //完成监听并将结果加入到主线程  
  250.                 onFinishListen.onFinish(this, result);  
  251.             }  
  252.             ;  
  253.   
  254.   
  255.         }  
  256.         if (onSystemFinishListen != null) {  
  257.             onSystemFinishListen.OnSystemFinish(this, result);  
  258.         }  
  259.         status = TaskStatus.finsh;  
  260.         return result;  
  261.     }  
  262.   
  263.     public abstract  R obtainData(Task<P,R> task, P parameter)throws Exception;  
  264.   
  265.     @Override  
  266.     public void update(Observable observable, Object data) {  
  267.         // 移除观察  
  268.         observable.deleteObserver(this);  
  269.         // 中断 停止关闭连接  
  270.         this.shutDownExecute();  
  271.         this.setWithout();  
  272.         if (this.thread != null) {  
  273.             this.thread.interrupt();  
  274.         }  
  275.         // 错误尝试次数为0  
  276.         this.tryAgainCount = 0;  
  277.     };  
  278.   
  279.     @Override  
  280.     public void run() {  
  281.   
  282.         try {  
  283.             Execute();  
  284.         } catch (Exception e) {  
  285.             e.printStackTrace();  
  286.             status = TaskStatus.error;  
  287.   
  288.   
  289.               
  290.             // 如果状态改变为处理完但不通知  
  291.             if (status != TaskStatus.without) {  
  292.                   
  293.                 if (onFinishListen != null) {  
  294.                     //将结果加入到主线程  
  295.                     onFinishListen.onFinish(this, result);  
  296.                 }  
  297.   
  298.             }  
  299.             if (onSystemFinishListen != null) {  
  300.                 onSystemFinishListen.OnSystemFinish(this, e);  
  301.             }  
  302.         }  
  303.   
  304.         //递归 避免新开线程   唤醒等待中的任务   
  305.         TaskQueue.getRunnable().notifyWaitingTask();  
  306.           
  307.     }  
  308.   
  309.   
  310.   
  311.     public Object getTag() {  
  312.         return tag;  
  313.     }  
  314.   
  315.     public Task setTag(Object tag) {  
  316.         this.tag = tag;  
  317.         return this;  
  318.     }  
  319.   
  320.     public Thread getThread() {  
  321.         return thread;  
  322.     }  
  323.   
  324.     public TaskStatus getStatus() {  
  325.         return status;  
  326.     }  
  327.   
  328.     public Object getParameter() {  
  329.         return parameter;  
  330.     }  
  331.   
  332.     public Task setParameter(P parameter) {  
  333.         this.parameter = parameter;  
  334.         return this;  
  335.     }  
  336.   
  337.     public OnStartListen getOnStartListen() {  
  338.         return onStartListen;  
  339.     }  
  340.   
  341.     public Task setOnStartListen(OnStartListen onStartListen) {  
  342.         this.onStartListen = onStartListen;  
  343.         return this;  
  344.     }  
  345.   
  346.     public OnProgressListen getOnProgressListen() {  
  347.         return onProgressListen;  
  348.     }  
  349.   
  350.     public Task setOnProgressListen(OnProgressListen onProgressListen) {  
  351.         this.onProgressListen = onProgressListen;  
  352.         return this;  
  353.     }  
  354.   
  355.     public OnFinishListen getOnFinishListen() {  
  356.         return onFinishListen;  
  357.     }  
  358.   
  359.     public Task setOnFinishListen(OnFinishListen onFinishListen) {  
  360.         this.onFinishListen = onFinishListen;  
  361.         return this;  
  362.     }  
  363.   
  364.     public OnSystemStartListen getOnSystemStartListen() {  
  365.         return onSystemStartListen;  
  366.     }  
  367.   
  368.     public OnSystemFinishListen getOnSystemFinishListen() {  
  369.         return onSystemFinishListen;  
  370.     }  
  371.   
  372.     public void setOnSystemFinishListen(  
  373.             OnSystemFinishListen onSystemFinishListen) {  
  374.         this.onSystemFinishListen = onSystemFinishListen;  
  375.     }  
  376.   
  377.   
  378.     public int getTaskID() {  
  379.         return taskID;  
  380.     }  
  381.   
  382.     public Task setTaskID(int taskID) {  
  383.         this.taskID = taskID;  
  384.         return this;  
  385.     }  
  386.   
  387.     public Object getResult() {  
  388.         return result;  
  389.     }  
  390.   
  391.     public int getTryAgainCount() {  
  392.         return tryAgainCount;  
  393.     }  
  394.   
  395.     public Task setTryAgainCount(int tryAgainCount) {  
  396.         this.tryAgainCount = tryAgainCount;  
  397.         return this;  
  398.     }  
  399.   
  400.     public int getTryAgainTime() {  
  401.         return tryAgainTime;  
  402.     }  
  403.   
  404.     private Task setTryAgainTime(int tryAgainTime) {  
  405.         this.tryAgainTime = tryAgainTime;  
  406.         return this;  
  407.     }  
  408.   
  409.       
  410.   
  411.     public Object  put(String key,Object value) {  
  412.         if(dataMap==null)  
  413.         {  
  414.             dataMap=new HashMap<String, Object>();  
  415.         }  
  416.         return dataMap.put(key, value);  
  417.     }  
  418.     public Object  get(String key,Object value) {  
  419.         if(dataMap==null)  
  420.         {  
  421.             dataMap=new HashMap<String, Object>();  
  422.         }  
  423.         return dataMap.get(key);  
  424.     }  
  425.   
  426.       
  427.     
  428. }  

 

  1. package demo2;  
  2.   
  3. import java.util.AbstractCollection;  
  4. import java.util.ArrayList;  
  5. import java.util.Collections;  
  6. import java.util.Iterator;  
  7. import java.util.LinkedList;  
  8. import java.util.List;  
  9. import java.util.Queue;  
  10. import java.util.Random;  
  11.   
  12. import demo2.Task.OnSystemFinishListen;  
  13. import demo2.Task.TaskStatus;  
  14.   
  15.   
  16. public class TaskQueue implements Runnable, OnSystemFinishListen {  
  17.     static String debug = "TaskQueue";  
  18.     @SuppressWarnings("unchecked")  
  19.     // 在等待的任务队列  
  20.      static LinkedList<Task> tasks_wait = new LinkedList<Task>();  
  21.   
  22.     public static class TaskQueueExpection extends Exception{  
  23.         TaskQueueExpection(String detailMessage) {  
  24.             super(detailMessage);  
  25.             // TODO Auto-generated constructor stub  
  26.         }  
  27.           
  28.     };  
  29.       
  30.     // 正在执行的任务  
  31.      static ArrayList<Task> tasks_running = new ArrayList<Task>();  
  32.     // 是否持续运行  
  33.     public static boolean isRun=true;  
  34.     // runnable保证线程安全  
  35.     private static TaskQueue runnable = new TaskQueue();;  
  36.     // 最大线程数  
  37.     static int ThreadMaxNum = 1;  
  38.   
  39.     public static TaskQueue getRunnable() {  
  40.         return runnable;  
  41.     }  
  42.   
  43.     // 如果队列线程为空或者停止则重新开启  
  44.     public static void serivesRun() {  
  45.         // TODO Auto-generated method stub  
  46.         boolean isCanSeriver=false;  
  47.         synchronized (tasks_running) {  
  48.             isCanSeriver=tasks_running.size() < ThreadMaxNum;  
  49.         }  
  50.        runnable.run();  
  51.     }  
  52.       
  53.     //获取正在执行的任务数  
  54.     public static int getRunningTaskCount() {  
  55.         synchronized (TaskQueue.tasks_running) {  
  56.             return TaskQueue.tasks_running.size();  
  57.         }  
  58.     }  
  59.     //设置最大任务数  
  60.     public static void setThreadMaxNum(int num) {  
  61.         TaskQueue.ThreadMaxNum = num<1?1:num>100?100:num;  
  62.     }  
  63.   
  64.     // 线程锁 如果等待队列的任务数不为空,并且当前线程数字少于最大线程数  
  65.     public static boolean taskRun() {  
  66.         synchronized (tasks_wait) {  
  67.             synchronized (tasks_running) {  
  68.                 return !tasks_wait.isEmpty()  
  69.                         && tasks_running.size() < ThreadMaxNum;  
  70.             }  
  71.         }  
  72.     }  
  73.     //开启新线程  
  74.     public void run() {  
  75.         // 线程锁 如果等待队列的任务数不为空,并且当前线程数字少于最大线程数  
  76.         Task newTask;  
  77.         while((newTask=getWaittingTask())!=null)  
  78.         {  
  79.             System.err.println("开启新线程处理一个新任务,ID:"+newTask.getTaskID());  
  80.             newTask.setOnSystemFinishListen(runnable);  
  81.             newTask.threadRun();  
  82.             newTask=null;  
  83.         }  
  84.          
  85.     }  
  86.       
  87.      //递归 避免新开线程   唤醒等待中的任务 但此方案会造成java.lang.StackOverflowError  
  88.      void notifyWaitingTask()  
  89.     {  
  90.         Task newTask;  
  91.         while((newTask=getWaittingTask())!=null)  
  92.         {  
  93.             System.err.println("唤醒旧线程处理一个新任务,ID:"+newTask.getTaskID());  
  94.             newTask.setOnSystemFinishListen(runnable);  
  95.             newTask.run();  
  96.             newTask=null;  
  97.         }  
  98.           
  99.     }  
  100.       
  101.     private  Task getWaittingTask()  
  102.     {  
  103.         Task t=null;  
  104.         //测试  
  105.         while (isRun && taskRun()) {  
  106.             // 添加带执行中动态数组中  
  107.             synchronized (tasks_wait) {  
  108.                 // 从等待任务的队列中获取并移除此列表的头(第一个元素)  
  109.                 t = tasks_wait.poll();  
  110.                 // 如果h为空则从队列重新取对象或者任务绑定的状态变化了  
  111.                 if (t == null || t.status == TaskStatus.without) {  
  112.                     System.out.println("任务取消 编号" + t!=null?String.valueOf(t.getTaskID()):"空任务");  
  113.                     continue;  
  114.                 }  
  115.             }  
  116.             synchronized (tasks_running) {  
  117.                 tasks_running.add(t);  
  118.             }  
  119.             System.out.println( "正在执行任务数" + tasks_running.size() + "/上限"  
  120.                     + ThreadMaxNum);  
  121.   
  122.             return t;  
  123.         }  
  124.         return t;  
  125.     }  
  126.       
  127.   
  128.     @Override  
  129.     public void OnSystemFinish(Task t, Object data) {  
  130.         // TODO Auto-generated method stub  
  131.         synchronized (tasks_running) {  
  132.             // 从处理中的动态数组中移除此任务  
  133.             tasks_running.remove(t);  
  134.             System.out.println( "执行队列中移除任务taskid=" + t.taskID);  
  135.             // 通知执行后续未处理的任务  
  136.             System.out.println("正在执行任务数" + tasks_running.size() + "/上限"  
  137.                     + ThreadMaxNum);  
  138.              
  139.             // 移除此名字映射  
  140.             if (t.getSingletonName() != null) {  
  141.                 Task.getNameTask().remove(t.getSingletonName());  
  142.             }  
  143.         }  
  144.           
  145.   
  146.     }  
  147.   
  148. }  


Demo代码下载地址

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-09-19 13:55  brave-sailor  阅读(1843)  评论(0编辑  收藏  举报