2.当很多条相同的指令以较短的时间间隔(1s左右)发送到通信设备时,通信设备只响应第一条,其他的不予响应。
解决方案
针对上述问题,我们就会想到通过使用队列和线程池来解决以上问题。我们可以将所有用户的指令依次放入队列中,线程池中只允许一个线程运行,而且线程执行完之后,还可以休眠一段时间,等通信设备反应过来的时候,再依次执行队列中的指令。
队列和线程池演示程序
1.WorkQueue.java该类实现了队列和线程池,详见如下
/* * $filename: WorkQueue.java,v $ * $Date: 2013-11-20 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ package edu.njupt.zhb; import java.util.LinkedList; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: [email protected] *2013-11-20 Nanjing,njupt,China *References:http://www.ibm.com/developerworks/java/library/j-jtp0730/index.html */ public class WorkQueue { private final int nThreads;//同时最多执行的线程个数 private final PoolWorker[] threads;//线程池 private final LinkedList queue;//线程队列 public WorkQueue(int nThreads) { this.nThreads = nThreads; queue = new LinkedList(); threads = new PoolWorker[nThreads]; for (int i=0; i<nThreads; i++) { threads[i] = new PoolWorker(); threads[i].start(); } } public void execute(Runnable r) { synchronized(queue) { queue.addLast(r); queue.notify(); } } private class PoolWorker extends Thread { public void run() { Runnable r; while (true) { synchronized(queue) { while (queue.isEmpty()) { try { queue.wait(); } catch (InterruptedException ignored) { } } r = (Runnable) queue.removeFirst(); } // If we don't catch RuntimeException, // the pool could leak threads try { r.run(); } catch (RuntimeException e) { // You might want to log something here e.printStackTrace(); } } } } }
这是我们的工作线程,在这个Demo中,工作线程只做一件事:将number的值加1,然后休眠,最后打印一下当前number的值。由于number是静态变量,因此我们就可以模拟一下,工作队列的一个执行情况。
/* * $filename: WorkThread.java,v $ * $Date: 2013-11-20 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ package edu.njupt.zhb; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: [email protected] *2013-11-20 Nanjing,njupt,China */ public class WorkThread extends Thread{ public static int number = 0; @Override public void run() { // TODO Auto-generated method stub try { number = number + 1; Thread.sleep(100); System.out.println("number = "+number); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
我们的线程池只允许一个线程同时执行,这样的结果是:打印number的值是从1-10顺序打印
/* * $filename: TestMain.java,v $ * $Date: 2013-11-20 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ package edu.njupt.zhb; import java.util.ArrayList; import java.util.List; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: [email protected] *2013-11-20 Nanjing,njupt,China */ public class TestMain { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub WorkQueue workQueue = new WorkQueue(1);//只允许同时运行1个线程 for (int i = 0; i < 10; i++) { WorkThread wThread = new WorkThread(); workQueue.execute(wThread); } } }
number = 1 number = 2 number = 3 number = 4 number = 5 number = 6 number = 7 number = 8 number = 9 number = 10
线程池中允许同时最多有5个线程一起执行
/* * $filename: TestMain.java,v $ * $Date: 2013-11-20 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ package edu.njupt.zhb; import java.util.ArrayList; import java.util.List; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: [email protected] *2013-11-20 Nanjing,njupt,China */ public class TestMain { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub WorkQueue wQueue = new WorkQueue(5);//允许同时运行5个线程 for (int i = 0; i < 10; i++) { WorkThread wThread = new WorkThread(); wQueue.execute(wThread); } } }
number = 5 number = 5 number = 5 number = 5 number = 5 number = 10 number = 10 number = 10 number = 10 number = 10
未经允许不得用于商业目的